Edited at

認証トークンをCookieに保存するのは卒業しよう

More than 1 year has passed since last update.

Webアプリケーションの認証トークン(セッション)はCookieヘッダで送信するのが一般的だとは思いますが、

そろそろこのCookieに依存した方法は負の遺産ではないでしょうか?

認証トークンの送信はRFC 7235で規定されているAuthorizationヘッダを使うと良いです。Basic認証とかDigest認証で使うやつですね。

実はBasicDigestの他にRFC 6750でBearerというスキームが登録されています。単一の文字列を認証情報として送信するためのスキームで、トークンを送信するのにピッタリです。

Authorization: Bearer <token>

参考: トークンを利用した認証・認可 API を実装するとき Authorization: Bearer ヘッダを使っていいのか調べた

その場合は、認証トークンはCookieではなくlocalStrage(またはsessionStorage)に保存することになると思います。

既に十分普及している仕様ですので、今後はこちらをスタンダードにしていきたいですね。


なぜ?

APIサーバとの相性が良いから。

APIサーバを立てるためのCORS設定決定版では触れませんでしたが、

コメントで指摘してもらったとおり、"Credential"な情報を扱うためにはAccess-Control-Allow-Credentials: trueの指定が必要になります。Cookieを送信する場合はこの"Credential"な情報を扱う場合に該当します。

その場合の制限としてAccess-Control-Allow-Origin: *が使えなくなります。何かしらのOrigin URLを指定する必要があります。

しかしながら、Authorization: Bearerで認証トークンを送信する場合は、この制限に引っかかりませんので、Access-Control-Allow-Credentials: trueは不要になり、Originの設定も必要なくなります。


(APIサーバにとって)Access-Control-Allow-Origin設定は必要か?

お断り: 以下の内容はあくまでも個人の見解です。

APIサーバの観点から見ると不要ではないか? と考えています。

そもそもSOP制約はクライアント(ブラウザ)側のセキュリティを守るためのものであって、第三者によって仕込まれたスクリプトなどが(本人から見て気が付かないうちに)別のサーバに送信されてしまうのを防ぐのが目的だったはずです。

(とはいえ回避策が溢れているので、もはや形骸化しているような気がしますが。)

サーバ側から見ると、クライアントから送られてきたリクエストは常に認証・validateしなければならないわけで、SOPは関係ないはずです。

ちゃんとクライアントを認証したいのであれば、IPアドレスではじくとか、トークンの検証1を行うとか、ちゃんとした手段で認証するべきです。

有効性が怪しく、半ば形骸化しているセキュリティ機構を使って、セキュリティが向上したと思い込んでしまう方が危険かな? と思うので、そういうのは避けたいところです。

それを理解した上で、お作法としてAccess-Control-Allow-Originを指定するのは良いとは思います。





  1. 存在性・有効性チェックは当然として、IPチェックによるセッションハイジャック対策も含みます。