動作環境
- Node.js 0.10.36
- Express 4.12.3
- Passport 0.2.1
- Socket.io 1.3.5
- OSX 10.10.2
で確認した。
事前準備
TwitterAppsで、認証に使用するURLを登録する。注意事項として
- Setting> Callback URLの入力
- Setting> ✔ Allow this application to be used to Sign in with Twitter
上記を忘れるとPINの入力を求められる。
やること
- PassportでtwitterOauthする
- PassportセッションをSocket.ioに渡す
- ブラウザにPassportセッションをemitする(handshakeの確認)
- 上記をなるべく少ないパッケージで
ということで、以下のライブラリで解決した。
package.json
{
"dependencies": {
"cookie-parser": "^1.3.4",
"express": "^4.12.3",
"express-session": "^1.10.4",
"passport": "^0.2.1",
"passport-twitter": "^1.0.3",
"socket.io": "^1.3.5"
}
}
package.jsonを使わない場合は
$ npm install cookie-parser express express-session passport passport-twitter socket.io
とします。
$ node app.js
app.js
// Generated by CoffeeScript 1.9.1
var TwitterStrategy, app, base, cookie, express, expressSession, expressSessionStore, http, io, parser, passport, passportConfig, server, socketio;
if ((base = process.env).PORT == null) {
base.PORT = 59798;
}
// dependencies
express = require('express');
expressSession = require('express-session');
expressSessionStore = new expressSession.MemoryStore;
passport = require('passport');
passportConfig = {
twitter: {
consumerKey: 'https://apps.twitter.com/で取得する',
consumerSecret: 'https://apps.twitter.com/で取得する',
callbackURL: "http://localhost:" + process.env.PORT + "/callback"
}
};
TwitterStrategy = require('passport-twitter').Strategy;
http = require('http');
socketio = require('socket.io');
cookie = require('cookie-parser/node_modules/cookie');
parser = require('cookie-parser');
// passport setup
passport.serializeUser(function(user, done) {
return done(null, user);
});
passport.deserializeUser(function(obj, done) {
return done(null, obj);
});
passport.use(new TwitterStrategy(passportConfig.twitter, function(token, tokenSecret, profile, done) {
return process.nextTick(function() {
return done(null, profile);
});
}));
// express setup
app = express();
app.use(expressSession({
store: expressSessionStore,
secret: 'keyboard cat',
resave: true,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.get('/', function(req, res) {
var html, ref;
html = "<script src=\"/socket.io/socket.io.js\"></script>\n<script>io.connect().on('authorized',function(session){document.querySelector('pre').innerHTML=session})</script>\n<h1>Passport for Socket.io1.3</h1>\n<pre></pre>";
if (((ref = req.session.passport) != null ? ref.user : void 0) == null) {
html += '<a href="/auth">twitterOauth</a>';
}
return res.end(html);
});
app.get('/auth', passport.authenticate('twitter'));
app.get('/callback', passport.authenticate('twitter', {
successRedirect: '/',
failureRedirect: '/failure'
}));
app.get('/failure', function(req, res) {
return res.end('だめでした');
});
// socket.io and http-server setup
server = http.Server(app);
server.listen(process.env.PORT);
io = socketio(server);
io.use(function(client, next) {
var cookies, sid, signedCookies;
signedCookies = cookie.parse(client.request.headers.cookie);
cookies = parser.signedCookies(signedCookies, 'keyboard cat');
sid = cookies['connect.sid'];
return expressSessionStore.get(sid, function(error, session) {
if (error != null) {
return next(error);
}
if (session.passport.user == null) {
return next('Guest');
}
client.session = session;
return next();
});
});
io.on('connect', function(client) {
return client.emit('authorized', JSON.stringify(client.session, null, 2));
});
passportConfig.twitter.consumerKey
とpassportConfig.twitter.consumerSecret
は、お手持ちの文字列に置き換えて実行してください。(ローカルで確認するだけならそのままでも動く)
- / にアクセスする( http://localhost:59798 )と、ログインの可否を表示する。
- /auth にアクセスすると、twitterOauthを行う。
- /callbackでPassportが成否を判断し、成功時はTwitterStrategyの第二引数を経由して、セッションに書き込む
- 成功なら / に戻り、socket.ioサーバーからセッションを受け取り、その内容を<pre>内にレンダリングする。
- 失敗なら /failureに飛び、「だめでした」となる
以上です。、楽しい沼ライフを