JWT(JSON Web Token)は、WebアプリケーションやAPIで認証・認可に関する情報をやり取りするためのトークン形式です。ログイン済みのユーザーを識別したり、APIリクエストにアクセス権限を添えたりするときに使われます。
ただし、JWTは「発行すれば安全になる」仕組みではありません。署名の検証、保存場所、有効期限、失効方法、ペイロードに入れる情報を適切に設計してはじめて、安全性と運用しやすさのバランスが取れます。
この記事では、JWTの基本構造、認証フロー、保存場所、メリット、実装時の注意点を順に整理します。
JWTとは
JWTは、JSON形式の情報をコンパクトな文字列として表し、クライアントとサーバーの間で受け渡しできるようにしたトークンです。主にログイン後のユーザーを識別する認証トークンや、APIにアクセスするためのトークンとして使われます。
ここでいう認証は「誰であるかを確認すること」、認可は「その人が何をしてよいかを判断すること」です。JWTには、ユーザーIDや発行時刻、有効期限、権限に関する情報などを含められます。
JWTはピリオドで区切られた3つの部分で構成されます。それぞれをBase64URLエンコードして連結することで、1つの文字列として扱えるようになります。
| 構成要素 | 役割 |
|---|---|
| ヘッダー | トークンの種類や署名アルゴリズムを示します。 |
| ペイロード | ユーザーID、発行時刻、有効期限などのクレームを入れます。 |
| 署名 | ヘッダーとペイロードが改ざんされていないかを確認するために使います。 |
JWTの構造
ヘッダー
ヘッダーには、トークンのタイプと署名に使うアルゴリズムを記述します。たとえばHMAC SHA-256を使う場合は、次のような形になります。
{
"alg": "HS256",
"typ": "JWT"
}
- alg: 署名に使うアルゴリズムです。
- typ: トークンのタイプです。JWTでは通常「JWT」と指定します。
ペイロード
ペイロードには、クレームと呼ばれる情報を入れます。クレームとは、トークンが伝える属性や状態のことです。たとえば、対象ユーザーを表す値や、トークンの発行時刻を含めることがあります。
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
- sub: ユーザーIDなど、対象を示す識別子です。
- name: ユーザー名などの情報です。
- iat: 発行日時を表す値です。
ペイロードに入れる情報は、必要最小限に絞ることが重要です。情報を詰め込みすぎるとトークンサイズが大きくなり、通信量や処理に影響します。また、不要な個人情報や機密情報を含めると、漏えい時の影響も大きくなります。
署名
署名は、ヘッダーとペイロードをもとに生成されます。サーバー側で署名を検証することで、トークンが途中で改ざんされていないかを確認できます。
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
署名は改ざん検知のための仕組みです。トークンの保存場所や通信経路まで含めて設計し、トークンそのものを不用意に露出させないことが重要です。
JWTを使った認証フロー
JWTを使う認証では、ログイン後に発行されたトークンをクライアントが保持し、その後のAPIリクエストに添えて送信します。基本的な流れは次のとおりです。
- ユーザー認証: ユーザーがログインし、サーバーがユーザー名やパスワードなどの資格情報を確認します。
- JWTの発行: 認証に成功すると、サーバーが署名付きのJWTを発行します。
- クライアントで保持: ブラウザやモバイルアプリが、用途に応じた場所にトークンを保存します。
- APIリクエストに添付: クライアントはリクエスト時にJWTを
Authorizationヘッダーへ含めます。 - サーバーで検証: サーバーは署名、有効期限、必要なクレームを確認します。
- リソースを返す: トークンが有効であれば、要求されたデータや機能を提供します。
リクエストでは、次のようにBearerトークンとして送る形が一般的です。
GET /protected-resource HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
JWTの保存場所と有効期限
JWTを安全に使ううえで、クライアント側の保存場所は重要です。保存方法にはそれぞれ利点と注意点があるため、アプリケーションの性質に合わせて選びます。
| 保存先 | 特徴 | 注意点 |
|---|---|---|
| ローカルストレージ | 実装しやすく、クライアント側で扱いやすい。 | XSS攻撃で読み取られるリスクがあります。入力値の無害化や表示処理の対策が欠かせません。 |
| Cookie | Secure属性やHttpOnly属性を使うことで、ブラウザ側の保護を強めやすい。 |
用途に応じて属性設定やリクエスト設計を慎重に決める必要があります。 |
JWTには通常、有効期限を設定します。アクセス用のJWTは短めにし、必要に応じてリフレッシュトークンで新しいトークンを発行する設計にすると、盗まれたトークンが長く使われるリスクを下げられます。
JWTのメリット
ステートレスな認証を設計しやすい
JWTを使うと、サーバーがセッション情報を常に保持しなくても、トークンの署名と内容を検証してユーザーを識別できます。複数のサーバーでAPIを運用する場合にも、構成をシンプルにしやすい点があります。
認証以外の情報も扱える
JWTには、認証に必要な情報だけでなく、アクセス権限やリソースに関する制約を含めることもできます。ただし、ペイロードに入れる情報が増えるほどサイズと管理上のリスクも増えるため、必要な情報に絞ることが前提です。
APIやクロスドメイン構成で使いやすい
JWTはHTTPヘッダーに含めて送信しやすいため、Webアプリケーション、モバイルアプリ、APIを組み合わせた構成でも扱いやすい形式です。CORSを含む構成では、認証方式だけでなく、許可するオリジンやヘッダーもあわせて設計します。
セキュリティで確認すべきポイント
JWTは便利ですが、設計や実装を誤ると不正アクセスの原因になります。導入時には、少なくとも次の点を確認します。
- 強い秘密鍵を使う: 署名に使う鍵が弱いと、トークンの改ざんや推測のリスクが高まります。
- HTTPSで通信する: トークンが盗聴されないよう、通信経路を暗号化します。
- 有効期限を短くする: アクセストークンを長期間有効にしすぎると、漏えい時の影響が大きくなります。
- アルゴリズムを明示的に選ぶ: 古い方式や弱い方式を避け、サーバー側で許可するアルゴリズムを明確にします。
- 失効の仕組みを用意する: ログアウト、リフレッシュトークンの失効、不正利用時の無効化を運用に含めます。
- ペイロードを最小限にする: ユーザー識別や認可に必要な情報だけを入れ、不要な個人情報や大きなデータは含めないようにします。
JWTのデメリットと注意点
トークンサイズが大きくなりやすい
JWTはペイロードに情報を含められるため便利ですが、情報を詰め込みすぎるとサイズが大きくなります。通信量やレスポンス速度に影響する可能性があるため、必要最小限のクレームに絞ることが大切です。
盗まれたトークンが利用される可能性がある
有効なJWTを第三者に盗まれると、有効期限が切れるまで不正に使われる可能性があります。短い有効期限、HTTPS、保存場所の設計、失効管理を組み合わせて対策します。
完全な失効管理には工夫が必要
JWTはステートレスに扱いやすい一方で、すべてのトークンをサーバー側で常時管理する方式とは性質が異なります。ログアウトや不正利用時に即時無効化したい場合は、ブラックリストや発行履歴の確認など、追加の管理方法を検討します。
導入前のチェックリスト
- JWTに入れるクレームは必要最小限か。
- アクセストークンとリフレッシュトークンの有効期限は適切か。
- トークンの保存場所とブラウザ側の攻撃対策を決めているか。
- サーバー側で署名、有効期限、必要なクレームを検証しているか。
- ログアウトや不正利用時の失効手順を用意しているか。
- APIの認可設計とトークンの権限範囲が一致しているか。
関連して読みたい記事
- 基本用語を短く確認したい場合: JWT(JSON Web Token)とは?
- FastAPIでJWT認証やOAuth2スコープを設計する場合: FastAPIセキュリティ実践ガイド:JWT認証・OAuth2スコープ・APIキーで守るモダンAPI設計
- 認証・認可設計全体を見直したい場合: はじめての本格セキュリティ設計:FastAPIの認証・認可ガイド
まとめ
JWTは、WebアプリケーションやAPIでトークンベース認証を実現するための有力な選択肢です。ヘッダー、ペイロード、署名という構造を理解し、保存場所、有効期限、失効方法まで含めて設計することで、扱いやすく安全な認証基盤に近づけられます。
特に重要なのは、強い秘密鍵を使うこと、HTTPSで通信すること、アクセストークンの有効期限を短くすること、不要な情報をペイロードに入れないことです。JWTはシンプルに見えますが、実運用では認証、認可、ログアウト、不正利用時の対応まで一体で考える必要があります。
greedenでは、システム開発やソフトウェア設計に関する相談を受け付けています。JWTを使った認証設計、API連携、セキュリティを考慮したアプリケーション開発でお悩みの際は、お問い合わせフォームからお気軽にご相談ください。

