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

Node.js+Passport+Google 認証を使ってみた

More than 1 year has passed since last update.

Passport とは

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

Passport を使ってみた

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

  • node 8.1.14
  • express 4.16.2
  • passport 0.4.0
  • passport-google-oauth 1.0.0

ワークスペースを作る

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

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

インストールする

$ npm install --save passport

参照 Passport | はじめに

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

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

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

Google 認証を使うための準備

Google 認証を使うために、Google サービスを使用するアプリケーションを事前に登録しておきます。

開発者としての Google アカウントを作っておきます。
その Google アカウントで Google Developer Console にログインします。
まず、プロジェクトを作成します。プロジェクト名は任意です。

参照 Google APIを使用するための設定(プロジェクトの作成 ・ 使用するAPIの設定) 第1回 - プログラミングノート

続いて、認証情報を作成します。
このとき、「OAuth クライアント ID」を選びます。
アプリケーションの種類は「ウェブアプリケーション」。
名前は任意です。
リダイレクト URL を設定します。設定すべき値は後述します。◆
「作成」すると、「クライアント ID」「クライアントシークレット」が取得できます。

参照 Google APIを使用するための設定(認証情報の登録) 第2回 - プログラミングノート

加えて、Google+ API を有効にしておきます。

参照 Google API を有効にする | MAGELLAN BLOCKS

これをしていないと実行時にエラーになります。

参照 Google Authentication Not Working · Issue #49 · scotch-io/easy-node-authentication · GitHub

Google を使って認証するための準備

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

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

$ npm install --save passport-google-oauth

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

app.js
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
passport.use(new GoogleStrategy({
        clientID: "上記で取得したクライアント ID",
        clientSecret: "上記で取得したクライアントシークレット",
        callbackURL: "上記で設定したロールバック URL"
    }, function(accessToken, refreshToken, profile, done){
        ◇◇  // ここで profile を確認して結果を返す
    }
));

結果を返すところは、

        if (profile) {
            return done(null, profile);
        }
        else {
            return done(null, false);
        }

この辺は Passport > Documentation > Google

ログイン URL を用意する

ここで用意された URL にアクセスすると、Google に認証を委譲します。

app.js
app.get('/auth/google', passport.authenticate('google', {
    scope: ['https://www.googleapis.com/auth/plus.login']
}));

ログイン画面を用意する

ログイン画面、例えば login.html を用意します。上記で準備した URL へのリンクを含めます。

login.html
<a href="/auth/google">Google でログインする</a> 

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

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

コールバック URL を用意する

Google で認証されると、コールバック先として事前に登録しておいた URL に飛んできます。
つまり、ここで用意した URL は、前述した Google 認証情報の設定で使用します。設定で使用するときは、相対パスでなく絶対パスを使います。

app.js
app.get('/auth/google/callback', 
    passport.authenticate('google', 
    function(req, res) {
        ◇◇  // 認証に成功したときの処理
    })
);

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

app.js
app.get('/auth/google/callback', 
    passport.authenticate('google', 
    function(req, res){
        res.redirect('/◇◇');
    })

遷移先はオプション指定で済ませられます。↓

app.js
app.get('/auth/google/callback', 
    passport.authenticate('google', {
        failureRedirect: '/◆◆',  // 失敗したときの遷移先
        successRedirect: '/◇◇',  // 成功したときの遷移先
    },
    function(req, res){

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

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

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

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

app.js
app.post('/login',
    passport.authenticate('google', {
        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

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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした