PassportによるFacebook認証(第一歩)

var Passport = require('passport');
var Facebook = require('passport-facebook');
// Facebook Strategyの設定を'fb'で登録。省略すると'facebook'で設定される
Passport.use('fb', new Facebook.Strategy({
        clientID: '1513567018936647',
        clientSecret: '2596-xxxxxxxxxsecretxxxxxxx-d126',
        callbackURL: "http://localhost:8080/auth/facebook/callback"
    },
    function(accessToken, refreshToken, profile, done) {
        // 2)Facebook認証のVerifyイベント
        console.log('Passport.verify');
        return done(null, profile);
    }
));
Passport.serializeUser(function(user, done) {
    // 3)セッションへ認証ユーザーを保存
    console.log('Passport.serializeUser');
    done(null, user);
});
Passport.deserializeUser(function(obj, done) {
    console.log('Passport.deserializeUser');
    done(null, obj);
});

var Express = require('express');
var app = Express();
app.use(Passport.initialize());
app.use(Passport.session());
// 1)認証始め
app.get('/auth/facebook', Passport.authenticate('fb'));
// 4)コールバック
app.get('/auth/facebook/callback',
    Passport.authenticate('fb', { failureRedirect: '/index.html'}),
    function(req, res) {
        console.log('success login');
        res.redirect('/success.html');
    }
);
app.use(Express.static('public'));
app.listen(8080);

Passportを利用してFacebookで認証するのに、ハマリどころは満載ですがコード自体はシンプルに書けます。シンプルにそぎ落としてみて最低限必要なことは以上の通りになりました。一見いらなそうなものも削るとエラー出ます。基本構造としては、1)'/auth/facebook'へのルーティングに仕込まれている、passport.authenticateミドルウェアで認証を始めます。引数に'fb'を渡すことで先に設定したFacebookStrategyを利用することを宣言しています。そしてFacebookに移動してそちらのログイン処理を行う最中に2)Strategyが持つVerifyイベントハンドラがコールされてAccess Tokenが手に入ります。その後に3)Strategyに設定するハンドラで認証ユーザーをセッションへ保存します。

ここまでの処理が成功していると、コールバックが戻ってきます。3)こちらも同じpassport.authenticateミドルウェアで、成功失敗の別に応じてリダイレクト。この後に取得したAccess Tokenを利用してFacebookAPIをコツコツ呼び出すことになります。

設定としてpassportのinitializeミドルウェアとsessionミドルウェアルーター登録するのが必須ですし、認証ユーザーのシリアライズがないとエラーを出しました。

f:id:masataka_k:20151117084100p:plain

Facebook側では、コールバックURLを登録する必要があります。localhost:8080をサンプルでは用いてるので、それはそれとしてFacebookアプリ設定ページにそのまま書いておかないと、指定コールバックURLが既知では無いということですぐに認証エラーを出す、いわば正しい動きをします。