JWT(JSON Web Token)とは? ― トークンに「情報」を詰め込む認証方式
JWT(JSON Web Token、ジョット)とは、JSON形式のデータをBase64でエンコードし、デジタル署名を付与したトークンです。主にWebアプリケーションの認証・認可で使われ、サーバーがセッション状態を保持しなくてもユーザーを識別できる「ステートレス認証」を実現します。RFC 7519で標準化されています。
映画館の入場チケットで例えると、従来のセッション方式は「チケットの半券を映画館の窓口で保管し、入場時に照合する」方法です。JWTは「チケット自体に座席番号・上映時間・購入者名が印刷され、偽造防止のホログラム(署名)が付いている」方法です。チケットを見るだけで情報が確認でき、窓口に問い合わせる必要がありません。
JWTの3つの構成要素 ― Header・Payload・Signature
JWTは3つのパートがドット(.)で連結された文字列です:xxxxx.yyyyy.zzzzz
Header(ヘッダー)
トークンの種類(typ: “JWT”)と署名アルゴリズム(alg: “HS256″や”RS256″など)を指定するJSONオブジェクトです。Base64Urlでエンコードされます。
Payload(ペイロード)
トークンに含める実際のデータ(クレーム)です。ユーザーID、権限、有効期限などを格納します。標準クレームとして、iss(発行者)、exp(有効期限)、sub(主体)、iat(発行時刻)などが定義されています。こちらもBase64Urlエンコードされますが、暗号化ではないため、誰でもデコードして中身を読めます。
Signature(署名)
Header + Payload + 秘密鍵を使って生成される署名です。トークンが改ざんされていないことを検証するために使います。HMAC-SHA256(共通鍵方式)またはRSA/ECDSA(公開鍵方式)が一般的です。
JWTによる認証フロー
JWTを使った認証は以下の流れで行われます。
ステップ1:ログイン — ユーザーがIDとパスワードを送信し、サーバーが認証します。
ステップ2:トークン発行 — 認証成功後、サーバーがJWTを生成してクライアントに返します。
ステップ3:トークン送付 — クライアントは以降のリクエストで、AuthorizationヘッダーにJWTを含めて送信します(Bearer eyJhbGci...の形式)。
ステップ4:検証 — サーバーはJWTの署名を検証し、有効期限を確認してリクエストを処理します。データベースへの問い合わせは不要です。
JWTとセッション方式の比較
| 比較項目 | JWT(トークン方式) | サーバーサイドセッション |
|---|---|---|
| 状態管理 | サーバーは状態を保持しない(ステートレス) | サーバーがセッションデータを保持(ステートフル) |
| スケーラビリティ | サーバー追加が容易(状態共有が不要) | セッションストア(Redis等)の共有が必要 |
| 即時無効化 | 困難(トークン発行済みのため) | 容易(セッションを削除するだけ) |
| データサイズ | ペイロードが大きいとトークンも大きくなる | セッションIDのみで軽量 |
| マイクロサービス | サービス間で署名検証だけで認証可能 | セッションストアへの依存が生まれる |
| CSRF対策 | Cookieに格納しなければCSRFの影響を受けない | Cookie利用のためCSRF対策が必須 |
JWTのセキュリティリスクと対策
リスク1:トークンの漏洩
JWTが盗まれると、有効期限内は不正利用が可能です。対策として、アクセストークンの有効期限を短く設定し(5〜15分)、リフレッシュトークンと組み合わせる方式が推奨されます。
リスク2:ペイロードの情報露出
JWTのペイロードはBase64エンコードであり暗号化ではありません。パスワードやクレジットカード番号などの機密情報を格納してはいけません。必要な場合はJWE(JSON Web Encryption)で暗号化します。
リスク3:「alg: none」攻撃
署名アルゴリズムを「none」に変更して署名検証を回避する攻撃です。サーバー側で許可するアルゴリズムを明示的にホワイトリスト指定することで防げます。
リスク4:秘密鍵の管理不備
HMAC方式の秘密鍵が漏洩するとトークンの偽造が可能になります。十分な長さの鍵を使用し、環境変数やシークレットマネージャーで安全に管理しましょう。
アクセストークンとリフレッシュトークンの使い分け
実務ではJWTを2種類のトークンに分けて運用するのが一般的です。
アクセストークン:APIへのアクセスに使用。有効期限は短め(5〜15分)。ペイロードにユーザー情報と権限を含みます。
リフレッシュトークン:アクセストークンの再発行に使用。有効期限は長め(数日〜数週間)。HttpOnly Cookieに保存し、サーバー側でも管理します(ブラックリスト方式で無効化可能)。
この2トークン方式により、「アクセストークンは短命でステートレス、リフレッシュトークンは長命だがサーバーで管理」という、利便性とセキュリティのバランスを実現できます。
よくある質問(FAQ)
Q. JWTはどこに保存すべきですか?
A. HttpOnly + Secure + SameSite属性のCookieに保存するのが最も安全です。localStorageはXSS攻撃で漏洩するリスクがあります。ただし、Cookie保存の場合はCSRF対策も併せて実装してください。
Q. JWTのトークンサイズが大きいのは問題ですか?
A. 通常は数百バイト〜1KB程度で、HTTPヘッダーに含めても大きな問題にはなりません。ただし、不要なクレームを詰め込みすぎるとリクエストサイズが増加するため、必要最小限の情報に留めましょう。
Q. JWTを使えばセッション管理は完全に不要になりますか?
A. いいえ。即座のログアウト(トークン無効化)や同時ログイン制限が必要な場合は、サーバー側でトークンの状態を追跡する仕組みが必要です。完全なステートレスにはトレードオフがあることを理解しておきましょう。
まとめ
JWTは、ステートレスな認証を実現するための強力な仕組みです。サーバーの負荷軽減とマイクロサービスとの親和性が大きな強みですが、トークン漏洩リスクや即時無効化の難しさといった課題もあります。アクセストークン+リフレッシュトークンの2トークン方式を採用し、署名アルゴリズムの検証やペイロードの最小化などのセキュリティ対策を徹底することが、安全なJWT運用の鍵です。

コメント