はじめに
トークンベース認証と JWT についての備忘録です。
改訂履歴
- 2026/07/30 : 初版公開。
本文
1. トークンベース認証とは
トークンベース認証とは、認証済みであることを示すトークンをクライアントへ発行し、そのトークンを利用して API などへのアクセスを許可する認証方式です。一般的な認証の流れは以下の通りです。
| 手順 | 内容 |
|---|---|
| 1 | ユーザーが ID / パスワードなどで認証する。 |
| 2 | サーバーが認証に成功するとトークンを発行する。 |
| 3 | クライアントがトークンを保持する。 |
| 4 | API リクエスト時にトークンを送信する。 |
| 5 | サーバーがトークンを検証し、アクセスを許可する。 |
補足
トークンベース認証では、トークンそのものが認証情報となります。そのため、第三者にトークンが漏洩すると不正利用される可能性があるため、適切に管理することが重要です。
2. セッションベース認証との違い
Web アプリケーションでは、従来から Cookie とセッション ID を利用したセッションベース認証が広く利用されています。トークンベース認証との違いは以下の通りです。
| 項目 | セッションベース認証 | トークンベース認証 |
|---|---|---|
| 認証情報 | セッション ID | トークン |
| サーバー側の状態 | 保持する | 基本的に保持しない |
| リクエスト時 | Cookie を送信 | トークンを送信 |
セッションベース認証では、サーバーがセッション ID とユーザー情報の対応を管理します。
一方、トークンベース認証では、クライアントが保持するトークンを送信し、サーバーがそのトークンを検証して認証を行います。
補足
トークンベース認証は「基本的に」サーバー側で状態を保持しない認証方式です。ただし、トークンの失効管理やリフレッシュトークンの管理など、実装によってはサーバー側で状態を保持する場合があります。
3. トークンの送信方法
認証が成功すると、サーバーはクライアントへトークンを発行します。クライアントは API リクエスト時に、そのトークンを HTTP の Authorization ヘッダーへ設定して送信します。一般的な形式は以下の通りです。
GET /api/users HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGci...
各項目の意味は以下の通りです。
| 項目 | 内容 |
|---|---|
Authorization |
HTTP の認証情報を送信するヘッダー |
Bearer |
Bearer 認証方式を表すキーワード |
eyJhbGci... |
認証済みであることを示すトークン(例) |
サーバーは受信したトークンを検証し、正当なトークンであれば、リクエストの処理を続行します。
補足
Bearer 認証では、トークンを所持していること自体が認証情報となります。そのため、トークンの漏洩を防ぐために HTTPS を利用して通信することが重要です。
4. JWT とは
JWT (JSON Web Token) とは、JSON 形式のデータを安全に送受信するためのトークン形式です。JWT は RFC 7519 で定義されており、OAuth のアクセストークンや OIDC の認証トークンなど、認証情報やユーザー情報などを格納するために広く利用されています。
補足
JWT には、署名を行う JWS (JSON Web Signature) と、暗号化を行う JWE (JSON Web Encryption) の 2 種類があります。多くの場合、シンプルで軽量な JWS の方が採用されるため、以降の説明も JWS で行います。
JWT は以下の 3 つの部分から構成されています。
| 要素 | 内容 |
|---|---|
| Header | トークンのメタ情報 |
| Payload | 認証情報や属性情報 (Claim) |
| Signature | トークンの改ざんを検知するための電子署名 |
JWT は、それぞれの情報を Base64URL エンコードし、. (ピリオド) で連結した文字列になっています。概念的には Header.Payload.Signature という状態ですね。各要素については、次節以降で説明します。
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlRhcm8iLCJleHAiOjE3ODU0NTYwMDB9.
QXlLQ0p4...
4-1. Header とは
Header とは、JWT のメタ情報を保持する部分です。主に署名アルゴリズムやトークンの種類などが格納されます。例えば、以下のような Header が含まれます。
{
"alg": "RS256",
"typ": "JWT"
}
各項目の意味は以下の通りです。
| 項目 | 由来 | 内容 |
|---|---|---|
alg |
Algorithm | 署名アルゴリズム。 |
typ |
Type | トークンの種類。通常は JWT が入る。 |
サーバーは Header の alg を確認し、指定された署名アルゴリズムに従って JWT の検証を行います。alg に指定される代表的な署名アルゴリズムは以下の通りです。
| アルゴリズム | 説明 |
|---|---|
HS256 |
HMAC using SHA256。 秘密鍵(共通鍵)を利用して署名・検証を行う。 |
RS256 |
RSASSA-PKCS1-v1_5 with SHA256。 秘密鍵で署名し、公開鍵で検証を行う。 |
ES256 |
ECDSA with P-256 and SHA256。 楕円曲線暗号方式を利用して署名・検証を行う。 |
NONE |
署名無し。 セキュリティが確保されておらず、通常使用することはない。 |
4-2. Payload とは
Payload とは、JWT に格納するデータを保持する部分です。Payload には、ユーザー情報や JWT の有効期限などを表す Claim と呼ばれる情報が格納されます。例えば、以下のような Payload が含まれます。
{
"sub": "1234567890",
"name": "Taro",
"role": "admin",
"iss": "https://auth.example.com",
"exp": 1785456000
}
サーバーは Payload に含まれる Claim を確認することで、JWT の有効期限や利用対象などを判断します。代表的な Claim は以下の通りです。
| 項目 | 由来 | 内容 |
|---|---|---|
iss |
Issuer | JWT の発行者 |
sub |
Subject | JWT の主体(ユーザー ID など) |
aud |
Audience | JWT の利用対象 |
exp |
Expiration Time | JWT の有効期限 |
nbf |
Not Before | 利用開始時刻 |
iat |
Issued At | JWT の発行日時 |
jti |
JWT ID | JWT を一意に識別する ID |
補足
exp や iat などの日時は UNIX エポック秒 (1970 年 1 月 1 日 00:00:00 UTC からの経過秒数) で表現されるようです。
また RFC 7519 で規定されている Claim 以外に、例えば name や role など、独自のカスタムクレームを定義することもできます。ただし、Header と Payload は Base64URL エンコードされているだけで暗号化はされておらず、Payload にパスワードや秘密鍵などの機密情報を含めてしまうと、セキュリティリスクになります。ペイロードに機密情報を含める必要がある場合 JWE (JSON Web Encryption) の利用を検討してください。
4-3. Signature とは
Signature は、JWT が改ざんされていないことを確認するための電子署名を保持する部分です。JWT の Signature は、Header と Payload を連結した文字列に対して署名アルゴリズムを適用することで生成されます。例えば、以下のような JWT がある場合、xxxxx.yyyyy の部分を秘密鍵などで署名し、その結果が zzzzz の部分になります。
xxxxx.yyyyy.zzzzz
サーバーは JWT を受け取ると、Header に指定された署名アルゴリズムを確認し、Signature を検証します。署名方式によって、検証に利用する鍵が異なります。
| 方式 | 代表例 | 署名 | 検証 |
|---|---|---|---|
| 共通鍵方式 | HS256 | 秘密鍵 | 同じ秘密鍵 |
| 公開鍵方式 | RS256 / ES256 | 秘密鍵 | 公開鍵 |
共通鍵方式では、署名と検証で同じ鍵を利用します。一方、公開鍵方式では、署名側だけが秘密鍵を保持し、検証側は公開鍵を利用するため、複数の API サービスで JWT を検証する構成に適しています。
補足
JWT の Signature は暗号化ではありません。Signature の目的は Payload の内容を隠すことではなく、JWT が正しい発行者によって作成され、内容が変更されていないことを確認することです。
5. JWT の検証処理
サーバーは JWT を受け取ると、トークンが正当なものかを検証します。一般的な検証の流れは以下の通りです。
JWT の検証では、主に以下の内容を確認します。
| 確認項目 | 内容 |
|---|---|
| Signature | JWT が改ざんされていないことを確認する |
exp |
有効期限が切れていないことを確認する |
nbf |
利用可能な時刻を過ぎていることを確認する |
iss |
信頼できる発行者が発行した JWT であることを確認する |
aud |
この API を利用するための JWT であることを確認する |
これらの検証が全て成功した場合、API サーバーは JWT を正当なトークンとして扱い、リクエストの処理を続行します。
6. JWT 利用時の注意点
JWT は認証や認可の仕組みとして広く利用されていますが、適切に設計・運用しなければセキュリティ上の問題につながる可能性があります。主な注意点は以下の通りです。
| 項目 | 対応主体 | 内容 |
|---|---|---|
| HTTPS を利用する。 | サーバー | 通信中の JWT の盗聴を防止するため、HTTPS を利用する。 |
alg に NONE を使用しない。 |
サーバー |
NONE の場合、署名無しでトークンを受け入れてしまうため、拒否や無効で設定する。 |
| 短い有効期限を設定する。 | サーバー | リプレイ攻撃対策のため、exp Claim を設定し、JWT が長期間利用されないようにする。 |
| 機密情報を格納しない。 | サーバー | Payload は暗号化されていないため、パスワードなどの機密情報は格納しない。 |
| 署名鍵を適切に管理する。 | サーバー | 秘密鍵や共通鍵が漏洩すると、不正な JWT を生成できる可能性がある。 |
| JWT の失効方法を検討する。 | サーバー | JWT は一度発行すると、有効期限まで利用できるため、失効方法をあらかじめ設計しておく。 |
| Cookie に保存する。 | クライアント | XSS 攻撃や CSRF 攻撃による窃取を防ぐため、JWT をブラウザの localStorage には保存せず、Cookie に保存する。Cookie には XSS 攻撃や CSRF 攻撃への対策として、HttpOnly や Secure、SameSite 属性などを適切に設定、サニタイジング処理を行う。 |
特に JWT は基本的にサーバー側で状態を保持しないため、発行後に特定の JWT だけを無効化することが容易ではありません。そのため、短い有効期限のアクセストークンと長い有効期限のリフレッシュトークンを組み合わせて利用することが一般的です。
このように、有効期限を短く設定することで、万が一アクセストークンが漏洩した場合でも、不正利用できる期間を短くできます。
おわりに
気付きがあれば、随時更新します。