仕組み
JWTは、ユーザー識別子などの情報をJSONとして持ち運ぶための形式です。
よく使われる署名付きJWTは、次の構造を持ちます。
header.payload.signature
この形式では、ペイロードはBase64URLでエンコードされているだけです。署名は改ざん検知に使われますが、内容を隠しません。
JWTには暗号化する形式もありますが、「JWTだから暗号化されている」と考えてはいけません。JWT仕様
PIIを不用意に入れない理由
PIIは、氏名、住所、メールアドレスなどの個人を識別し得る情報です。
署名付きJWTに含めると、そのトークンを入手した人は内容を読めます。また、ログや開発ツールなどに残った場合、個人情報まで露出します。
そのため、認証・認可に必要な情報へ絞ります。
| クレーム | 用途 |
|---|---|
sub |
誰についてのトークンか |
iss |
誰が発行したか |
aud |
どのサービス向けか |
exp |
いつまで受け入れられるか |
ユーザーIDも個人と結び付く情報なので、「IDだけなら無条件に安全」という意味ではありません。
有効期限が必要な理由
盗まれたBearerトークンは、通常、所持者が利用できます。有効期限は、そのトークンを受け入れる期間を限定します。
ただし、期限はトークンを消す仕組みではありません。サーバーが期限を検証して拒否することで機能します。
JWTの基本仕様では exp は任意ですが、アクセストークンとして利用する設計では、期限を必須にするなどのルールが必要です。JWT:有効期限
ログアウトと失効は別問題
クライアントからJWTを削除しても、すでにコピーされたトークンは消えません。
即時失効が必要なら、失効リストやセッション状態の確認などを組み合わせます。期限を短くする方法もありますが、再認証や更新処理とのバランスが必要です。
デコードだけでは認証できない
サーバーは、少なくとも用途に応じて次を検証します。
- 信頼する鍵で署名が正しいか。
- 許可した署名アルゴリズムか。
- 想定する発行者か。
- 自分のサービス向けのトークンか。
- 有効期限などの時間条件を満たしているか。
ライブラリでJSONを取り出せたことは、正当なトークンだという証拠になりません。JWTのセキュリティ指針
設計上の要点
JWTは認証を自動で安全にする仕組みではなく、検証ルールと運用を必要とする情報形式です。