unhurried

コンピュータ関連ネタがほとんど、ときどき趣味も…

MEANスタックでの認証状態制御

MEANスタックでユーザー認証を実装しようとしたときに、Node.js(サーバー)とAnglarJS(クライアント)の役割分担で迷ってしまいました。 具体的には、認証状態を昔ながらのWebアプリのようにHTTP Cookieで管理するか、それとも最近のモバイルアプリのように認証トークンを発行して、サーバーはWeb API提供に徹する方式にするかというものです。

最近の定番を調べてみたところ、とても説得力のある記事があったのでご紹介します。

auth0.com

この記事では、Cookieよりも認証トークンを推奨していて、その理由をいくつか挙げています。(ここでは認証トークンはJWTのように署名付きトークンを前提に議論されています。)

  • クロスドメインのバックエンドにて認証状態制御ができる。(Cookieは同一ドメインに制限される。)
  • クライアント状態をサーバーのセッション保存領域に保存しなくて良く、サーバーをスケールできる。(これは厳密には署名付きCookieでも同じことができます。参考:Play Frameworkのセッション管理
  • クライアント側は静的なソースにできるため、CDNで配信できる。
  • 認証トークンの発行方式を変えることで、任意の認証スキームに対応できる。(おそらくはCookieのようにWebフォームでの認証に限定されない、ということを言いたいのだと思います。)
  • モバイルアプリ開発時に認証の仕組みがそのまま使える。
  • 認証トークンは意識的に送信するコードを記述する必要があるため、CSRF対策が不要となる。
  • セッションIDをデータベースから検索しなくて良く、パフォーマンスが良い。(これも厳密には署名付きCookieで同じことができます。)
  • Procatorを使ってテストを実装する場合にログイン画面を特別扱いしなくて良い。(あるテストフレームワークに限定した話のようです。)
  • 認証トークンに標準的なJWTを利用することで、既存のライブラリを活用できる。

個人的にぐっときたのはクロスドメイン、CDN、モバイルアプリ開発あたりです。
ID(+認可)管理サーバーを1つ作って、そこで認証トークンを発行し、各リソースサーバーはそれぞれのドメインで自由に作る。また、AngularJS(クライアント)のコードは静的にしてCDNで配信して、モバイルアプリ開発時は単純にAngularJSコードを移植すれば良い(場合によっては埋め込んでしまえる)、となります。