ELW株式会社 テックブログ

リアルなログをそのままお届けします。

JWTを理解する

ELWでエンジニアをしております。井立田です。

今回はJWTとJWTを用いたセッション管理について見ていきます。

JWTとは

  • JSON Web Tokenの略
  • JSON形式でデータを安全にやりとりするためのトーク
  • 電子署名によって改ざんを検知できる

JWTの構造

<ヘッダー>.<ペイロード>.<署名>
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNzAwMDAwMDAwLCJleHAiOjE3MDAwMDM2MDB9.
Dv8pI3nO_AK9Y2VsGShvMJtVf1YV8wzTlb8xq2PbLRw

ヘッダー

ペイロード

  • クレームと呼ばれる情報を保持する
  • JWTは改ざんは検出できるが、誰でもBase64でデコードして読めるため、機密情報は含めない
  • ペイロードの主要クレーム

    • sub : ユーザーIDやエンティティの識別子
    • name : ユーザー名
    • iat : トークン発行日時
    • exp : トークンの有効期限
    • nbg : トークンが有効になる日時
    • aud : トークンの対象者
    • iss : トークンの発行者
      {
        "sub": "1234567890",
        "name": "John Doe",
        "iat": 1700000000,
        "exp": 1700003600
      }
    
  • このJSONをBase64Urlエンコードする

      eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNzAwMDAwMDAwLCJleHAiOjE3MDAwMDM2MDB9
    

署名

  • JWTの改ざんを防ぐためデジタル署名を付与する
  • ヘッダー・ペイロードを連結し、秘密鍵で署名することで生成される
  • 検証はヘッダー・ペイロードから署名を再計算して、一致するかどうかを調べる
HMACSHA256(
  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" + "." +
  "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNzAwMDAwMDAwLCJleHAiOjE3MDAwMDM2MDB9",
  シークレットキー
)
Dv8pI3nO_AK9Y2VsGShvMJtVf1YV8wzTlb8xq2PbLRw

セッション管理でJWTを利用する

セッションIDを用いたセッション管理

サーバー側でセッションIDを管理する方式(ステートフル)

  1. ログインリクエス
    • クライアントがログイン情報を送信
  2. セッションの作成
    • 認証に成功した場合、サーバー側でセッションIDを作成
    • セッションIDをDBやメモリ(redisなど)に保存
  3. セッションIDの送信
    • セッションIDをクライアントのCookieに保存
  4. セッション確認
    • クライアントがリクエストを送る際にCookieに含まれたセッションIDをサーバーに送信
    • サーバーがセッションIDを検証し、有効ならリソースを返す

JWTを用いたセッション管理

サーバー側でセッション情報を持たず(ステートレス)、トークンでユーザー識別を行う 方式

  1. ログインリクエス
    • クライアントがログイン情報を送信
  2. JWTを発行
    • 認証に成功した場合、サーバー側でJWTを発行
  3. JWTの送信
    • JWTをクライアントで保存(Cookie、メモリ)
  4. JWTの検証
    • サーバーはJWTの署名を検証し、内容が改ざんされていないか確認
    • トークンが有効ならリソースを返す

補足

「セッションベース認証」や「JWT認証」は一般的に利用されている用語だが、厳密には適切な名称ではないと感じる。

どちらも、認証方式 ではなく、認証後のセッション管理方式 を表している。

認証とは

  • 認証とは、ユーザーが 誰であるか を確認するプロセスを指す。

セッション管理とは

  • 認証情報を維持し、継続的にリクエストを処理できるようにする仕組み。

したがって、上記の図では 1. ログインリクエストが認証に該当する。

サーバー側でセッションIDを管理するか、JWTを利用するかは 認証後の認証情報を維持する仕組み である。

このように、「セッションベース認証」「JWT認証」という言葉は、正確には 「セッション管理方式」の違いを表している。

JWTのメリット

  • ステートレス
    • サーバー側でセッションを管理する必要がない
    • 複数サーバー構成でもセッション共有が不要
  • セキュリティ
    • 改ざん検知が可能
  • コンパクト
    • JSONを利用するためXMLよりもサイズが小さい
  • 汎用性

参考

議事録

  • JWT認証というのは厳密には正しくないのではないか
    • 認証はユーザーが誰であるかを確認すること
    • 認証の仕組みとJWTと別である。あくまで認証後に認証情報を維持する仕組みとしてJWTを利用しているだけ
  • Next Authの場合、トークンはクッキーに保存されている
    • クッキーに保存する場合、http onlyでないと危険