Node.jsで困るのはある機能を満たすためにどのパッケージを使っていいか分からないことです。発展途上ということで納得しましょう。発展途上というか生態系。
今回、Facebook認証をするためのモジュールを探しました。 stackoverflowで色々比較コメントがあり、それらやREADMEを参考にしました。
connect-authというのは名前もいいし、それなりのStar数もあります。シンプルでよさそうなのですが、よく使い方が分かりません。人気があるのは後発のeveryauthのようです。しかし、ドキュメントを読んでみてもどうもピンときません。なにか、感性が合わないような気がしました。
そこで、Passportを試すことにしました。 http://passportjs.org/guide/facebook/にドキュメントがあります。everyauthと比較するとコーディング量は多いかもしれませんが、なんとなくこちらの方が合う気がします。それでも、accessTokenが欲しいだけの場合は、userオブジェクトなんて作らなくてもいいのですけど。これはeveryauthも同じ(?)なので我慢するとします。
簡単に今使ってみた方法を紹介します。
まずは、ライブラリのロードです。サンプルをコピペしただけです。
var passport = require('passport');
var FacebookStrategy = require('passport-facebook').Strategy;
続いて、FacebookStrategyの設定です。accessTokenだけ欲しかったので、それをuserオブジェクトにします。必要であれば、profileとかも入れればよいでしょう。userオブジェクトは、req.user
で参照できるので、accessTokenはreq.user.accessToken
になります。
passport.use(new FacebookStrategy({
clientID: process.env.FACEBOOK_APP_ID,
clientSecret: process.env.FACEBOOK_SECRET,
callbackURL: process.env.CALLBACK_URL
}, function(accessToken, refreshToken, profile, done) {
done(null, {
accessToken: accessToken
});
}));
サンプルにあったシリアライザも入れておきます。これは書かなくてもよさそうと思ったのですが、ソースみてもデフォルトがあるように見えず、念のためいれておきます。
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(obj, done) {
done(null, obj);
});
強制的にログインさせるmiddlewareです。一度、ログインを促すページを表示するほうが親切かもしれません。
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
next();
} else if (req.url.lastIndexOf('/auth/', 0) >= 0) {
next();
} else {
res.redirect('/auth/facebook');
}
}
expressの設定です。セッションを使うのでその設定が必要です。
var app = express();
app.use(express.cookieParser());
app.use(express.session({ secret: 'foobar' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(ensureAuthenticated);
最後に、expressのルートの設定をします。failureRedirectは暫定です。
app.get('/auth/facebook', passport.authenticate('facebook'));
app.get('/auth/facebook/callback', passport.authenticate('facebook', {
successRedirect: '/',
failureRedirect: '/auth/loginfailed'
}));
app.get('/auth/loginfailed', function(req, res) {
res.send('login failed');
});
以上、こんな感じで使うようです。/auth/facebookのようなルートを設定しなければならないのを面倒と考えるか、分かりやすいと考えるかが、Passportを受け入れられるかの境目かもしれません。
コメント