Tech Sketch Bucket of Technical Chips by TIS Inc.

node.js+express+PassportでOAuth認証

Pocket

軽めの話題を

毎回割と「濃い目」の記事が多いこのTech-Sketchですが、今回は軽めの内容として、nodejsとそのモジュールであるPassportを利用した他サービスとの認証連携を説明しようと思います。

PassportはConnectやExpressベースのWebアプリケーションに認証の仕組みを組み込むことができるモジュールです。単純なローカルでのユーザ名・パスワードによる認証から、OpenIDやOAuthを利用した認証もカバーしています。それぞれの認証の方式はstrategyとして選択することが可能で、簡単に認証に関する実装を追加することができます。OpenID/OAuthで認証を行う場合のstrategyは、メジャーなサービスに対してのものはnpmでインストールできる形ですでに多数用意されています。

具体的にどのようなstrategyが用意されているかは、以下のリンク先を参照してください。

Passportのサイト
OpenIDを利用するために既存で用意されているstrategy
OAuthを利用するために既存で用意されているstrategy

今回やってみること

今回の説明ではexpressで作成したWebアプリからFacebookにアクセスし、OAuth認証を行なってFacebookのGraph APIで友達一覧を取得して表示するところまでを行なってみます。

友達一覧を取得するGraph APIはOAuth2.0を利用しており、クライアントサイドフロー(implicit flow)とサーバサイドフロー(authentication code flow)のどちらかを利用して認証を行うことが可能です。今回はサーバ上のWebアプリがFacebookに対して認証を要求しますので、サーバサイドフローを利用するということになります。

ここでは、Facebookでの認証フローの細かい解説はしませんので、以下のリンクの公式サイトを参照してください。

FacebookのAPI利用時の認証に関する公式サイト

準備

まずはnode+express+passportでアプリを作成できるように、nodeと必要なモジュールをインストールします。ここではnode自体とexpressのインストールについては割愛します。nodeをすでに利用したことがある方にはお馴染みでしょうが、nodeについては、バージョンアップも頻繁なのでnvm(node version manager)を利用して複数バージョン利用可能な環境を作っておくと便利です。nvmについては以下のリンクを参照してください。

nvm

expressとpassportについてはnpm(node package manager)を利用してインストールします。npmに関してもnodeを利用したことがある方にはお馴染みなものなので、もはや細かい説明は必要ないかと思います。nvmでnodeをインストールしていれば、npmはインストールされているはずです。npmが利用できる状態であれば、express、passportともにインストールは簡単です。npm installコマンドを実行して、それぞれインストールすることになります。

expressはすでにインストール済みとして、以下アプリの作成を行っていきます。

アプリの雛形作成とモジュールのインストール

expressでアプリの雛形を作成しておきます。今回は単純に友達リストを取得してくるだけのアプリなのでsimple_friends_listとしました。以下の通り作成します。

次にPassportを利用するのに必要なモジュールをインストールします。ここでは作成したアプリのローカルへモジュールをインストールすることにしますので、アプリのディレクトリに移動し、npmでインストールしてください。

続いてFacebook用のstrategyのモジュールをインストールします。

これモジュールが利用できる状態になりましたので、実際にアプリに組込んでいきます。

認証の組込みとAPIへのアクセス

アプリのディレクトリ化にあるapp.jsを適宜エディタなどで開いて、まずはモジュールを利用するための宣言を追加していきます。

続いて初期化の追加をします。app.jsでconfigureメソッドに以下の記述を追加します。

追加しているのはexpress自体のセッションミドルウェアの記述とpassportの初期化、passport.session()ミドルを利用するための記述です。expressでのセッションのもち方はConnectのセッションミドルウェアに依存しています。Connectのデフォルトはmemory storeですが、redis storeなど他の実装を利用する場合は適宜express.sessionの部分の宣言を変えてください。expressのセッションを有効にしたら、passportでのログインセッションを永続化できるようpassport.session()を有効にしておきます。

あとは実際の認証フローに関連した記述を追加していきます。まず以下のようにFacebook StrategyにFacebookのOAuth認証に必要なパラメータと、認証後の処理を記述するコールバック関数をわたしてインスタンスを生成し、利用できるようにします。

Facebookアプリをすでに作ったことがある方にはおなじみかと思いますが、アプリ登録時に割り振られるID、Secretと認証後のリダイレクト先のURLを渡してアクセスできるようにそれぞれの値を入れておきます。認証後に呼ばれるコールバック関数については、返されるProfile情報から、適宜自分のアプリに必要なユーザ情報を取得して永続化するようにしておきます。ここでは単純にProfileのすべてをセッションで保持するような実装にしています。必要に応じて個別に用意したDB上で永続化しておくための実装をコールバック関数にしておくとよいです。

また、後で友達の一覧を取得するのにアクセストークンを利用するので、こちらも保持しておきます。実際にプロダクションレベルでアプリを作成する場合には、このアクセストークンの保持の仕方は、先程のユーザ情報と同様、きちんとDB上に保存しておくなど、当然適当に扱わないようにする必要がありますが、ここでは簡単にしておくために、単純にセッションに持たせています。

合わせてセッションを利用しているので、ユーザに関連する情報でセッションに保持しておくもののシリアライズ、デシリアライズのための関数についても追加しておきます。

ここではProfile全てを単純にシリアライズ、デシリアライズするようにしてあります。DBに永続化しているものに関しては、そちらを利用するのであれば、IDのみにするなどしておくとよいです。

あとはルートを記述します。

passportのauthenticate関数を2度呼び出していますが、一度目はFacebookにアクセスして認証を受けるための呼出し、2度目はFacebookから認証が終わってリダイレクトされてきた後に、その後の処理を実行するための呼出しです。ここでは認証が無事成功した場合には'/'にリダイレクトしています。この'/'表示時にFacebookのGraph APIにアクセスして友達の一覧を取得し表示することになります。

表示のための実装は以下。

routesディレクトリ以下のindex.jsで'/'呼出し時にFacebookのGraph APIのフレンド一覧を取得できるAPIにアクセスして一覧を取得し、view表示しています。ここでセッション上に保持しているProfileのIDと認証後に受け取ったアクセストークンを利用しています。IDについては先程のシリアライズ、デシリアライズの処理を通っているので、reqからuser.idという呼出しで取得できるようになっています。

実際にアクセスして表示したイメージは以下。
friends_list_small.png

今回は説明を割愛しますが、ログアウトが必要な場合には'/logout'などのルートを作って、そこでreq.logout()を呼出すことでログアウトできます。

以上ざっとPassportを利用したFacebookでのOAuth認証について説明してみました。比較的簡単に利用できるモジュールだと思いますので、Facebook以外の認証でも使ってみるとよいかもしれません。

エンジニア採用中!私たちと一緒に働いてみませんか?