node.jsでpassportとrequestを使ってHTTP Digest認証を実装した話

  • 投稿日:
  • by

Railsより簡単にSNSを作れるようにすることを目指したライブラリ social-cms-backend を改良しました。

これまでは、認証機構はFacebook連携のみが実装されていたのですが、 Facebookに依存したくないアプリを作るケースも考え、 今回HTTP Digest認証も入れました。 Formによるパスワード認証も一応あったのですが、これは動作確認用で、not for production扱いです。 やはり生のパスワードがネット上を流れるのはよくないということで。 (SSLなしの想定)

Digest認証のサーバ側は passport-http を使いました。 Digest認証をそのまま使うのは不便なので、2つ工夫をしました。 一つは、RememberMeクッキーを併用することで、 もう一つは、JavaScriptでDigestを生成して認証することです。 Digest認証の最大の問題はUIがブラウザ依存だということです。 realmで指定する文字列しか指定できません。 また、ブラウザがパスワードを覚えてしまうので、アプリ側からログアウトできません。 そこで、DigestのヘッダーをJavaScriptで生成しました。 これは、完全な仕様通りではありません。細かい話は省きますが、 今回のサーバ実装ではたまたまnonceのサーバ側のチェックを省略していたのでできてしまったまでです。 ただ、もしチェックではじかれた場合でも通常のブラウザのDigest認証に fallbackするだけなので、リスクが増えるわけではないはずです。 逆に、パスワードを一回目で間違えた場合もfallbackしてしまいます。 このあたり、いい解決法がないようです。 (そもそもDigest認証の仕様に従わず、なんちゃってDigestにしてしまえばいいのかも)

Digest認証のクライアント側として request をunit testで使いました。使おうとしてから気づいたのですが、 Digest認証の実装が不十分だったので、直してPull Requestしておきました。 無事マージされました。

social-cms-backendはangular.jsでTwitterっぽいアプリを作るのに 便利なのですが、ちょっと使い方にくせがあります。 もっとチュートリアルを増やさないと使えるレベルにならないかも。