30歳からのプログラミング

30歳無職から独学でプログラミングを開始した人間の記録。

Node.jsでTwitterAPIのリクエストトークンを取得

Node.jsでTwitterAPIを弄っており、認証機能を作りたいと思っている。
まずはリクエストトークンを取得する必要がある、というところまでは分かったが、その先で苦労した。

検索してみても、Node.jsでTwitterOAuth認証をやっている記事は少なく、あまり見つけられなかった。
あったとしても、4,5年前のものが多く、かなり古いバージョンのフレームワークが使われていたりして、参考にしづらかった。

いろいろと試してみても

{"errors":[{"code":32,"message":"Could not authenticate you."}]}

が返ってきてしまって苦しんでいたが、何とか出来たので、記録として残しておく。

フレームワークは使わず、Node.jsで直接APIを叩く。

参考資料

この記事が非常に参考になった。必要な知識は全てここから得た。

同じサイトのこの記事も読んでおくと、理解が深まる。

アプリケーションの登録

上述のページを参考にして行う。何も迷うことはないと思う。

必要なnpmパッケージをインストール

$ npm install request

これだけ。これ以外は、標準モジュールのcryptoを使うだけ。

コード

下記のコードのcallbackUrlconsumer_keyconsumer_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);
});