LoginSignup
17
19

More than 5 years have passed since last update.

passportのtwitterOauthをsocket.ioに渡す(Express4)

Last updated at Posted at 2015-03-22

動作環境

  • 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の入力を求められる。

やること

  1. PassportでtwitterOauthする
  2. PassportセッションをSocket.ioに渡す
  3. ブラウザにPassportセッションをemitする(handshakeの確認)
  4. 上記をなるべく少ないパッケージで

ということで、以下のライブラリで解決した。

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

とします。

`git clone`して`cd`して`npm start`するだけで[動くサンプルを用意した][2]ので、忙しい人やCoffeeScriptスキーの人はそちらを参照して欲しい。そちらのほうが見易い
$ 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.consumerKeypassportConfig.twitter.consumerSecretは、お手持ちの文字列に置き換えて実行してください。(ローカルで確認するだけならそのままでも動く)

  • / にアクセスする( http://localhost:59798 )と、ログインの可否を表示する。
  • /auth にアクセスすると、twitterOauthを行う。
  • /callbackでPassportが成否を判断し、成功時はTwitterStrategyの第二引数を経由して、セッションに書き込む
  • 成功なら / に戻り、socket.ioサーバーからセッションを受け取り、その内容を<pre>内にレンダリングする。
  • 失敗なら /failureに飛び、「だめでした」となる

以上です。、楽しい沼ライフを

参考

17
19
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
19