JWT(JSON Web Token)は、JSON形式の情報をトークンとして受け渡すための形式です。
認証やシステム間のデータ交換に利用でき、サーバーが署名を検証することで、受け取った情報が途中で書き換えられていないかを判断できます。
ただし、JWTを採用するだけで認証が安全になるわけではありません。
保存場所、トークンの有効期間、失効方法、ペイロードに入れる情報まで含めて設計する必要があります。
JWTの仕組み
JWTは、Header、Payload、Signatureの3つの部分をピリオドでつないだ文字列です。
3つの構成要素
- Header(ヘッダー):トークンの種類と、署名に使用するアルゴリズムを示します。
- Payload(ペイロード):ユーザーIDや認可情報など、受け渡したいデータを格納します。
- Signature(署名):ヘッダーとペイロードを基に生成し、受信側が改ざんの有無を検証するために使います。
たとえば、ヘッダーには次のようなJSONを入れます。
{
"alg": "HS256",
"typ": "JWT"
}
ペイロードには、次のようなデータを格納できます。
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
各部分をBase64URLで扱える形にし、ピリオドで連結すると、次のようなトークンになります。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
署名と暗号化の違い
JWTのペイロードは、通常のエンコードを施しただけであり、暗号化された秘密情報ではありません。
トークンを入手した人はペイロードの内容を読み取れるため、見られて困る情報をそのまま格納しない判断が必要です。
署名の役割は内容を隠すことではなく、受信側が正しく検証したときに改ざんを検知できるようにすることです。
JWTのメリットと向く場面
JWTは、サーバー側のセッション情報をリクエストごとに参照しない構成を取りやすい点に特徴があります。
この特徴は、複数のサーバーやサービスが同じ認証情報を扱う構成で役立つことがあります。
- 分散システムやサーバーレス構成で、中央のセッション管理への依存を抑えたい場合
- API間やマイクロサービス間で、短期間だけ有効な認証情報を受け渡す場合
- ペイロード内の限定された情報をクライアント側でも参照したい場合
また、セッション確認のためのデータベースアクセスを省ける設計では、認証処理の負荷を抑えられる可能性があります。
実際の速度や拡張性はシステム全体の構成に左右されるため、JWTを使えば必ず高速になるとは限りません。
FastAPIでの具体的な設計例は、JWT認証、OAuth2スコープ、APIキーを扱うFastAPIセキュリティガイドで確認できます。
採用前に確認したい注意点
ブラウザ内の保存場所
JWTをローカルストレージに保存すると、ブラウザ上で動くスクリプトから読み取れます。
XSS(クロスサイトスクリプティング)によって悪意のあるスクリプトが実行された場合、保存したトークンが窃取される可能性があります。
HttpOnly Cookieに保存すれば、ブラウザ上のスクリプトからトークンを直接読み取れないため、この窃取経路を減らせます。
ただし、保存場所を変えるだけでWebアプリケーション全体の安全性が保証されるわけではありません。
ペイロードの内容
ペイロードは暗号化されていないため、秘密情報の保管場所として扱うことはできません。
格納するデータを必要最小限に絞れば、情報露出の範囲とトークンサイズを抑えやすくなります。
トークンのサイズ
JWTは、ペイロードに入れるデータが増えるほど長くなります。
CookieやHTTPヘッダーで送る場合は通信のたびにトークンが付くため、不要なデータを詰め込むと通信負荷も増えます。
即時失効の難しさ
発行済みのJWTは、基本的に有効期限まで利用できます。
漏洩時などにすぐ無効化するには、サーバー側で拒否対象のトークンを管理して照合する方法が必要になります。
この管理を追加すると、サーバー側に状態を持たないというJWTの利点は小さくなります。
JWT以外の選択肢
認証方式は、JWTの採用を前提に決めるのではなく、失効、管理、連携の要件から選びます。
| 選択肢 | 仕組み | 利点 | 注意点 |
|---|---|---|---|
| セッションベース認証 | サーバー側でセッション情報を管理し、クライアントはセッションIDをCookieで送ります。 | 漏洩時などに対象セッションを無効化しやすい方式です。 | サーバー側でセッションを保存し、複数サーバー間でも扱えるように管理する必要があります。 |
| OAuth2とセッション | OAuth2のフローを使い、トークンやログイン状態をサーバー側で管理します。 | アクセストークンの利用範囲を設定できます。 | 構成要素が増えるため、設定と運用が複雑になります。 |
| APIキー | リクエストにAPIキーを付けて送ります。 | 比較的単純な仕組みで、利用者やアプリごとのアクセスを管理できます。 | キーの保管、更新、漏洩時の交換を継続して管理する必要があります。 |
OAuth2を候補に含める場合は、OAuth2とOpenID Connect(OIDC)の違いも整理しておくと、目的に合う仕組みを選びやすくなります。
JWTを選ぶための確認項目
- サーバー側でセッションを管理しない構成にする理由があるか
- トークンを即時に失効させる要件があるか
- ブラウザで使う場合、どこに保存するかを決めているか
- ペイロードに秘密情報や不要なデータを入れていないか
- 有効期間と漏洩時の対応を決めているか
JWTは、分散したサービス間で短期間の認証情報を扱う場面や、サーバー側のセッション参照を減らしたい場面で候補になります。
一方、即時失効を優先する場合や、サーバー側でセッションを無理なく管理できる場合は、セッションベース認証のほうが要件に合うこともあります。
保存場所、失効方法、ペイロードの内容を先に決め、その要件を満たせる場合にJWTを採用するのが現実的です。
