Node.jsでTwitterAPIを弄っており、認証機能を作りたいと思っている。
まずはリクエストトークンを取得する必要がある、というところまでは分かったが、その先で苦労した。
検索してみても、Node.jsでTwitterのOAuth認証をやっている記事は少なく、あまり見つけられなかった。
あったとしても、4,5年前のものが多く、かなり古いバージョンのフレームワークが使われていたりして、参考にしづらかった。
いろいろと試してみても
{"errors":[{"code":32,"message":"Could not authenticate you."}]}
が返ってきてしまって苦しんでいたが、何とか出来たので、記録として残しておく。
参考資料
この記事が非常に参考になった。必要な知識は全てここから得た。
同じサイトのこの記事も読んでおくと、理解が深まる。
アプリケーションの登録
上述のページを参考にして行う。何も迷うことはないと思う。
必要なnpmパッケージをインストール
$ npm install request
これだけ。これ以外は、標準モジュールのcrypto
を使うだけ。
コード
下記のコードのcallbackUrl
、consumer_key
、consumer_secret
の値を、登録したアプリのものに変える。
そして実行すると、リクエストトークンを取得できる。
コードはまったく整理していないのでもっと綺麗に出来ると思うが、取り敢えず、これで動く。
2016/11/29追記
コードを若干改善。以前のものでも動くが、こちらのほうが望ましい。
const request = require('request'), crypto = require('crypto'); const requestUrl = 'https://api.twitter.com/oauth/request_token'; const callbackUrl = '登録したコールバックURL'; const consumer_key = 'Consumer Key (API Key)'; const consumer_secret = 'Consumer Secret (API Secret)'; const keyOfSign = encodeURIComponent(consumer_secret) + "&"; let params = { oauth_callback: callbackUrl, oauth_consumer_key: consumer_key, oauth_signature_method: 'HMAC-SHA1', oauth_timestamp: (()=>{ const date = new Date(); return Math.floor( date.getTime() / 1000 ) ; })(), oauth_nonce: (()=>{ const date = new Date(); return date.getTime(); })(), oauth_version: '1.0' }; Object.keys(params).forEach(item => { params[item] = encodeURIComponent(params[item]); }); let requestParams = Object.keys(params).map(item => { return item + '=' + params[item]; }); requestParams.sort((a,b) => { if( a < b ) return -1; if( a > b ) return 1; return 0; }); requestParams = encodeURIComponent(requestParams.join('&')); const dataOfSign = (()=>{ return encodeURIComponent('POST') + '&' + encodeURIComponent(requestUrl) + '&' + requestParams; })(); const signature = (()=>{ return crypto.createHmac('sha1', keyOfSign).update(dataOfSign).digest('base64'); })(); params['oauth_signature'] = encodeURIComponent(signature); let headerParams = Object.keys(params).map(item => { return item + '=' + params[item]; }); headerParams = headerParams.join(','); const headers = { 'Authorization': 'OAuth ' + headerParams }; //オプションを定義 const options = { url: requestUrl, headers: headers }; //リクエスト送信 request.post(options, function (error, response, body) { console.log(body); });