[セキュリティ] 認証(Authentication)・認可(Authorization)

認証・・・アクセスしてきたユーザーの身元を確認すること(=提示された身分証の確認)

認可(承認)・・・リソースに対するアクセス権限をユーザーに与えること(=入場券の発行)

従来のセッションによる認証

cookieによってセッションIDが返される

JSON Web Token (JWT)

サーバー上に認証状態を保持しないステートレスな認証方式

アクセストークン

  • 署名によって改ざんを検証できる、ステートレスなJWT文字列(例:HMAC-SHA256で署名され、ペイロードにsubやexpなどのクレームを含むもの)
  • 有効期限が短い(例:5〜15分)
  • サーバーがJSONとして送信する({"access_token": "..."} のような形式が一般的)
  • クライアントがメモリに保存する(Local Storageやcookieに保存してはいけない)

リフレッシュトークン

  • 一意で予測不可能なランダム文字列(例:256ビット以上の暗号論的ランダムバイト列をBase64エンコードしたもの)
  • 有効期限が長い(例:1〜7日)
  • サーバーがhttpOnly cookieとして送信する(=実際には全リクエストのHTTPヘッダーにhttpOnly cookieが含まれているため、明示的に送信する必要はない。クライアントはJavaScriptでアクセスできない)
  • 必ず有効期限を設定しなければならない(=期限が切れると再ログインが必要になる)
  • リフレッシュトークンは一度使用されたら即座に無効にすべきであり、再利用は認めてはならない(=使い回し禁止)。
    もし同じリフレッシュトークンが再度使用された場合、それは漏洩・不正アクセスの可能性があるため、すべてのリフレッシュトークンを無効化する、ユーザーを強制ログアウトするなどの措置を取らなければならない。

処理の流れ

認可時にサーバーがアクセストークン(JSON)とリフレッシュトークン(httpOnly cookie)を発行する(=リフレッシュトークンはサーバー側で設定するだけで、明示的にクライアントに送信する必要はない)

クライアントがアクセストークン(=APIリクエストのAuthorizationヘッダー内のBearer <access_token>)を伴って、(アクセス保護された)各種APIエンドポイントにアクセスする

アクセスリクエストの都度、サーバー側のミドルウェアがアクセストークンを検証する

アクセストークンが有効期限切れの場合、サーバーはクライアントに401 Unauthorizedレスポンスを返す

クライアントは(新しいアクセストークンを発行してもらうために)サーバーのトークンリフレッシュエンドポイント等に(httpOnly cookieのリフレッシュトークンを伴って)リクエストを送信する

サーバーはリフレッシュトークンをエンドポイントとデータベースを用いて検証する

リフレッシュトークンが有効期限内である場合、サーバーは新しいアクセストークンを生成し、クライアントに送信する

クライアントは新しいアクセストークンを使って(アクセス保護された)各種APIエンドポイントにアクセスする

必要な場合、サーバーはリフレッシュトークンを早期に期限切れにし、ユーザーを強制ログアウトさせることができなければならない

注意点

JWTのペイロードに機密情報を含めてはいけない