ELWでエンジニアをしております。井立田です。
今回はJWTとJWTを用いたセッション管理について見ていきます。
JWTとは
JWTの構造
<ヘッダー>.<ペイロード>.<署名>
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNzAwMDAwMDAwLCJleHAiOjE3MDAwMDM2MDB9. Dv8pI3nO_AK9Y2VsGShvMJtVf1YV8wzTlb8xq2PbLRw
ヘッダー
使用する署名アルゴリズムを指定する
{ "alg": "HS256", "typ": "JWT", }
-
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
ペイロード
- クレームと呼ばれる情報を保持する
- JWTは改ざんは検出できるが、誰でもBase64でデコードして読めるため、機密情報は含めない
ペイロードの主要クレーム
sub
: ユーザーIDやエンティティの識別子name
: ユーザー名iat
: トークン発行日時exp
: トークンの有効期限nbg
: トークンが有効になる日時aud
: トークンの対象者iss
: トークンの発行者
{ "sub": "1234567890", "name": "John Doe", "iat": 1700000000, "exp": 1700003600 }
-
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNzAwMDAwMDAwLCJleHAiOjE3MDAwMDM2MDB9
署名
HMACSHA256( "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" + "." + "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNzAwMDAwMDAwLCJleHAiOjE3MDAwMDM2MDB9", シークレットキー )
Dv8pI3nO_AK9Y2VsGShvMJtVf1YV8wzTlb8xq2PbLRw
セッション管理でJWTを利用する
セッションIDを用いたセッション管理
サーバー側でセッションIDを管理する方式(ステートフル)
- ログインリクエスト
- クライアントがログイン情報を送信
- セッションの作成
- 認証に成功した場合、サーバー側でセッションIDを作成
- セッションIDをDBやメモリ(redisなど)に保存
- セッションIDの送信
- セッションIDをクライアントのCookieに保存
- セッション確認
JWTを用いたセッション管理
サーバー側でセッション情報を持たず(ステートレス)、トークンでユーザー識別を行う 方式
- ログインリクエスト
- クライアントがログイン情報を送信
- JWTを発行
- 認証に成功した場合、サーバー側でJWTを発行
- JWTの送信
- JWTをクライアントで保存(Cookie、メモリ)
- JWTの検証
- サーバーはJWTの署名を検証し、内容が改ざんされていないか確認
- トークンが有効ならリソースを返す
補足
「セッションベース認証」や「JWT認証」は一般的に利用されている用語だが、厳密には適切な名称ではないと感じる。
どちらも、認証方式 ではなく、認証後のセッション管理方式 を表している。
認証とは
- 認証とは、ユーザーが 誰であるか を確認するプロセスを指す。
セッション管理とは
- 認証情報を維持し、継続的にリクエストを処理できるようにする仕組み。
したがって、上記の図では 1. ログインリクエストが認証に該当する。
サーバー側でセッションIDを管理するか、JWTを利用するかは 認証後の認証情報を維持する仕組み である。
このように、「セッションベース認証」「JWT認証」という言葉は、正確には 「セッション管理方式」の違いを表している。
JWTのメリット
- ステートレス
- サーバー側でセッションを管理する必要がない
- 複数サーバー構成でもセッション共有が不要
- セキュリティ
- 改ざん検知が可能
- コンパクト
- 汎用性
参考
- https://jwt.io/introduction
- https://zenn.dev/swy/articles/0e8de582f4e7f3
- https://zenn.dev/collabostyle/articles/b08c7f29a2e94c
- https://qiita.com/knaot0/items/8427918564400968bd2b
議事録
- JWT認証というのは厳密には正しくないのではないか
- 認証はユーザーが誰であるかを確認すること
- 認証の仕組みとJWTと別である。あくまで認証後に認証情報を維持する仕組みとしてJWTを利用しているだけ
- Next Authの場合、トークンはクッキーに保存されている
- クッキーに保存する場合、http onlyでないと危険