Help us understand the problem. What is going on with this article?

Node.js+Express+Passport を使ってみた

More than 1 year has passed since last update.

Passport とは

Passport は Node.js のための認証ミドルウェアです。認証リクエストをおこなうための必要最低限の機能をもつように設計されています。
公式 Passport - Node.jsのための、シンプルで使いどころを選ばない認証モジュール

Passport を使ってみた

Passport をインストールして、ユーザID&パスワード認証するところまで、使ってみました。

  • node 0.10.24
  • express 4.13.4
  • passport 0.3.2

ワークスペースを作る

まず、Node.js+Express のワークスペースを作ります。

参考 Node.js、Express.js入門 - ぺーぺーSEのブログ

インストールする

$ npm install --save passport

参照 Passport | はじめに

以下をソースコードに追加します。

app.js
var passport = require('passport');
app.use(passport.initialize());

参照 Passport | 設定 ミドルウェアの設定

ユーザID&パスワード認証するための準備

Passport を使って認証確認する処理を書きます。

まず、認証ストラテジをインストールします。

$ npm install --save passport-local

以下をソースコードに追加します。

app.js
var LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(function(username, password, done){
    // ここで username と password を確認して結果を返す
}));

結果を返すところは、

    if (なんらかのエラー) {
        return done(エラー内容);
    }
    else if (失敗) {
        return done(null, false);
    }
    else if (成功) {
        return done(null, username);
    }

この辺は Passport | 設定 検証用コールバックに関する設定

ログイン画面を用意する

ログイン画面、例えば login.html を用意します。

login.html
<form action="/login" method="post">
    <div>
        <label>ユーザーID:</label>
        <input type="text" name="username"/>
    </div>
    <div>
        <label>パスワード:</label>
        <input type="password" name="password"/>
    </div>
    <div>
        <input type="submit" value="ログイン"/>
    </div>
</form>    

この例では /login に POST します。

/login に GET するとこの画面を表示するようにしておきましょう。

app.js
app.get('/login', function(req, res){
    res.sendFile(__dirname + '/◇◇/login.html');
});

ログイン情報を受取って認証処理に渡す

/login に POST されたら、その情報を受取って認証処理に渡すようにします。

$ npm install --save body-parser
app.js
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));

app.post('/login',
    passport.authenticate('local'),
    function(req, res){
        // 認証成功するとここが実行される
    }
);

passport.authenticate() には、post() で受け取った username と password が渡されます。上記で準備した認証確認する処理が実行され、その結果が返ってきます。

この辺までは Passport | ユーザーID & パスワード

認証すると通常はページ遷移します。

app.js
app.post('/login',
    passport.authenticate('local'),
    function(req, res){
        res.redirect('/◇◇');

遷移先はオプション指定することができます。

app.js
app.post('/login',
    passport.authenticate('local', {
        failureRedirect: '/◆◆',  // 失敗したときの遷移先
        successRedirect: '/◇◇',  // 成功したときの遷移先
    }),

認証成功したときは URL 遷移せずに処理することが多いでしょうか。

app.js
app.post('/login',
    passport.authenticate('local', {
        failureRedirect: '/◆◆',  // 失敗したときの遷移先
    }),
    function(req, res){
        ◇◇  // 成功したときの処理

セッションを無効にして使う

Passport は認証成功したとき認証情報をセッションに保存します。API サーバとして実行するときは、リクエストごとに認証処理する必要があります。このときはセッションを無効にして使用します。

app.js
app.post('/login',
    passport.authenticate('local', {
        session: false,

この辺までは Passport | 認証

セッションを有効にして使う

Passport は認証成功したとき認証情報をセッションに保存します。Express でセッションを使えるようにしておきましょう。

$ npm install --save express-session
app.js
var session = require('express-session');
app.use(session({
    secret: '○○',
}));
app.use(passport.session());

passport.serializeUser(function(user, done) {
    done(null, user);
});

passport.deserializeUser(function(user, done) {
    done(null, user);
});

この辺は Passport | 設定 セッション管理に関する設定

どのページでも認証確認する

これまでのコードでは、ログイン画面以外のページでは認証確認されません。どのページでも認証確認されるようにしましょう。

まず、ページのリクエストを貰ったとき認証済か確認する関数を用意します。

app.js
function isAuthenticated(req, res, next){
    if (req.isAuthenticated()) {  // 認証済
        return next();
    }
    else {  // 認証されていない
        res.redirect('/login');  // ログイン画面に遷移
    }
}

ページごとに確認処理を入れるようにします。例えば、

app.js
app.get('/◆◆', isAuthenticated, function(req, res){
    ◇◇  // 認証済のとき実行される

参考 express - Documentation for "ensureAuthentication" "isAuthenticated" passport's functions? - Stack Overflow

おわりに

とりあえず Node.js+Express+Passport を使って、ユーザID&パスワード認証できるようになりました。
Passport は、Facebook や Twitter と連携した認証もできます。
また、ログアウトの処理も用意しないといけません。
これらについては、改めて。

tinymouse
SI 企業の SE であり、日曜プログラマであり、二児の父。
https://tinymouse.hatenadiary.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away