Kikuchy's Second Memory

技術のこととか、技術以外のこととか、思ったことを書き留めています。

Express + Passport でお手軽ユーザー認証

最近流行の node.js と、Webアプリ用のミドルウェア Express で Web アプリケーションを書いています。
ユーザー認証の機能が欲しかったので、 Passport というユーザー認証用のミドルウェアを使ってみる事にしました。

同じような機能を実現するミドルウェアには everyauthがあります。が、 ログイン画面などへのルーティングの仕方を、 express のルーティングと一緒に書けなくて気持ち悪いので、今回は見送ることにしました。


Passport の特徴はこんな感じ。らしい。

  • Strategy というオブジェクトを切り替えることで、様々な認証方法に対応
    • Local(よくある、ユーザー名とパスワードでの認証)
    • Twitter
    • Facebook
    • とかとか。140以上あるらしいです。
  • 認証成功時、失敗時の処理の書き方が簡単
  • アプリケーションのルーティングの上書きをしない


では今回作る Web アプリの方針。

  • 自分のサーバーの DB でユーザーを管理する
    • DB には MongoDB を使用
    • DB のミドルウェアには mongoose を使用
    • パスワードは SHA-256 で暗号化して保存
  • セッションにユーザーを持たせる
    • シリアライズして、余計な情報は持たないようにする
    • User コレクションのオブジェクトを持ってくると、パスワードまでついて来てしまうため
  • セッションはメモリに持つ
  • ログインに失敗したら、失敗した旨はフラッシュメッセージで表示する

早速始めましょう。作業は以下の環境で行いました。

まず、適当な所にアプリケーションのひな形を用意します。セッションを使うので、 session オプションを忘れずに。
今回は名前を passporttest にしました。

$ express passporttest
$ cd passporttest

次に、 package.json を編集して、 passport を導入する準備をします。
以下のように、 passport, passport-local, connect-flash, mongoose を書き足します。
いい加減に最新版を使っていますが、実際に公開して稼働させるときにはバージョンを固定した方が良いでしょう。

{
  "name": "application-name",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "3.3.1",
    "jade": "*",
    "passport": "*",
    "passport-local": "*",
    "connect-flash": "*",
    "mongoose": "*"
  }
}

依存関係を解決します。

$ npm install

app.js と、付随するビューを編集します。今回はサンプルのアプリケーションなので全部 app.js の中に書いてしまいますが、実際に開発する際は、適当にモジュールを分けた方が良いでしょう。

動かすとこんな風になるかと思います。

f:id:kikuchy:20130703040052p:plain

おもむろにlogin 画面へ。

f:id:kikuchy:20130703040159p:plain

Email に "aaa@example.com"、Password に "aaa" を入れてエンターを押下すると、インデックスに戻ります。ログイン成功です。

f:id:kikuchy:20130703040253p:plain

さて、 member_only にアクセスすると…

f:id:kikuchy:20130703040447p:plain

ちゃんとメールアドレス付きで表示されています!
ログインできましたね!

ログアウトした後に member_only にアクセスすると、ログイン画面に飛ばされることも確認してください。
他にも、ログイン画面で間違ったパスワードを入れるとか、登録されていないメールアドレスを入れるとか…
なかなかよくできています。




なんだこれだけかよ、と思われる方もいらっしゃるかも知れないですが、ログイン処理やログイン済みかどうかを見張る機能を一から自前で書き上げるのはなかなか骨が折れます。
また、こうして「実装すべき所が決まっているもの」を使う事で、実装し忘れる機能を減らす事ができます。
その手間を節約できるという点で、こういったプラグインやミドルウェアの存在は欠かせません。

ただ少し、機能が少ない感は否めません。パスワードの暗号化など、自動でやって欲しい機能はあるでしょう。
今回使った LocalStrategy はかなりシンプルなコードでできているので、自前でパスワードの暗号化機能などを足しても面白いかも知れません。


参考