背景
諸般の事情で、
- 公式サイトを開かずにキーワードのツイートの検索
- フォローをせず特定のユーザに関係するツイートの検索
といったなんだかわからない事情でこれまでJSONPで扱えるTwitterの検索APIを
常用していたのですが、1.0から1.1ベースへAPIが変更する影響か
これが最近エラーを頻繁に返すようになってしまい、何とかしたい一心でOAuth認証する検索用のAPIを叩きたく調べたところ。
【Node.js】OAuth認証でPassportが最強に使いやすいなるページをGoogleに紹介され、なるほどPassportっていうのが
良さそうだと思って始めた。
ところが、PassportはいろいろなSNSに対応しているが、
あくまでもログイン処理に限定している臭いことが薄々分かりつつある今日この頃だったのですが、なんとかしてみました。
元にするソース
元にするのはPassport-twitterのサインインの例
https://github.com/jaredhanson/passport-twitter/blob/master/examples/signin/app.js
対応方針
Passport-twitterは内部でoauthを使用してる
TwitterStrategyの_oauthという名前で格納されている。
ユーザー情報と一緒にアクセストークンはもらっている
profileの中に入れることで、
req.userとしてリクエストオブジェクト経由でアクセス可能となる。
元のソースの以下を
passport.use(new TwitterStrategy({
consumerKey: TWITTER_CONSUMER_KEY,
consumerSecret: TWITTER_CONSUMER_SECRET,
callbackURL: "http://127.0.0.1:3000/auth/twitter/callback"
},
function(token, tokenSecret, profile, done) {
// asynchronous verification, for effect...
process.nextTick(function () {
// To keep the example simple, the user's Twitter profile is returned to
// represent the logged-in user. In a typical application, you would want
// to associate the Twitter account with a user record in your database,
// and return that user instead.
return done(null, profile);
});
}
));
これを、以下の様に、
TwitterStrategyを生成しているところを、後続の処理で付けるように変数で受ける
ようにして、認証成功時にもらえるアクセストークンをreqオブジェクトから
アクセスできるように、入れておく。(上記ソースのprofileがreq.userでアクセスできる)
var ts = new TwitterStrategy({
consumerKey: TWITTER_CONSUMER_KEY,
consumerSecret: TWITTER_CONSUMER_SECRET,
callbackURL: "http://127.0.0.1:3000/auth/twitter/callback"
},
function(token, tokenSecret, profile, done) {
// asynchronous verification, for effect...
// アクセストークンをユーザ情報の中に入れて、API叩く際にこれを参照する。
profile.twitter_token = token;
profile.twitter_token_secret = tokenSecret;
process.nextTick(function () {
// To keep the example simple, the user's Twitter profile is returned to
// represent the logged-in user. In a typical application, you would want
// to associate the Twitter account with a user record in your database,
// and return that user instead.
return done(null, profile);
});
}
)
passport.use();
肝心の1.1APIの叩き方
oauthモジュールのやり方でいけます。
ts._oauth.getProtectedResource(
'https://api.twitter.com/1.1/search/tweets.json?q='+keyword,
'GET',
req.user.twitter_token,
req.user.twitter_token_secret,
function (err, data, response) {
if(err) {
res.send(err, 500);
return;
}
var jsonObj = JSON.parse(data);
// あとはお好みで
res.render('search', {
user: req.user,
result: jsonObj
});
});