JWT の解説: 構造、クレーム、デコード方法
更新 2026-07-06
現代のウェブ API を扱ったことがあれば、JWT に出会っているはずです — ログイン応答や Authorization ヘッダーに現れる、点が 2 つ入った長い意味不明の文字列。不透明に見えますが、構造がわかれば驚くほど読めます。このガイドは JSON Web Token とは何か、中に何があるのか、署名がどう動くのか、避けるべきセキュリティミスを説明します。
JWT は何のためか
JSON Web Token(JWT) は、クレームの束 — 「これはユーザー 42 で 10:05 にサインインした」といった主張 — を運ぶ、コンパクトで自己完結的な方法です。主な用途は認証です: ログインするとサーバーが JWT を発行し、アプリはリクエストごとにそれを送り返し、サーバーは毎回セッションストアで照合する代わりにそれを信頼します。トークンが情報自体を持つので ステートレス(stateless) と呼ばれます。
3 つの部分
すべての JWT は点でつながれた 3 つの Base64URL エンコード区間です: header.payload.signature。
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiJ9.3x9kQ... └──── header ────┘ └── payload ──┘ └ signature ┘
1. ヘッダー(Header)
トークンに関するメタデータ — 署名アルゴリズム(alg、例: HS256)と種類(typ: JWT)。デコードすると小さな JSON にすぎません:
{ "alg": "HS256", "typ": "JWT" }2. ペイロード(Payload)
クレーム — 実際のデータ。いくつかの名前は標準化されています(登録済みクレームと呼ぶ):
sub— 主体(subject)、通常はユーザー ID。iss— 発行者(issuer)、トークンを作った主体。aud— 対象(audience)、誰のためか。exp— 有効期限(Unix タイムスタンプ)。iat— 発行時刻(Unix タイムスタンプ)。
その exp と iat の値は 1970 年以降の秒数です — 実際の日付として読む必要があれば、タイムスタンプ変換ツール が人が読める時刻に変えてくれます。
3. 署名(Signature)
署名はトークンを信頼できるものにするものです。発行者はヘッダーとペイロードを取り、秘密鍵を使って暗号学的な署名を生成します。鍵を持つ人は、ヘッダーとペイロードが改変されていないことを検証できます — ペイロードの 1 文字を変えるだけで署名はもう一致しません。
最も重要な理解点
JWT は署名されているのであって暗号化されていません。 ヘッダーとペイロードは Base64URL でエンコードされているだけで、誰でも デコードして読めます — 鍵は不要です。署名は 改ざん を防ぎますが、読むこと は防ぎません。
実務上の帰結: JWT のペイロードに秘密を決して入れないこと。パスワードもクレジットカード番号も個人データも — ペイロードは公開だと考えましょう。当サイトの JWT デコーダ に任意のトークンを貼れば自分で確認できます。ヘッダーとクレームを即座に、すべてブラウザ内で読みます(トークンは端末を離れません)。内部では単なる Base64 デコードで — デコーダはその手間を省くだけです。
検証 vs. デコード
この 2 つは別の行為で、混同するのは本物のセキュリティバグです。デコード はペイロードを読みます — 誰でもでき、何も証明しません。検証 は鍵で署名を確認し、トークンが本物で改変されていないことを確かめます。サーバーは信頼する前にすべてのトークンを 検証 しなければなりません; デコードだけでは認証ではありません。
よくある落とし穴
- 未検証のトークンを信頼する — クレームに従って動く前に、必ずサーバー側で署名を確認しましょう。
- 有効期限を無視する —
expを尊重しましょう; 期限切れのトークンは拒否すべきです。 - ペイロードに機微データを保存する — 誰でも読めます。
- `alg: none` の罠 — かつて一部のライブラリが「署名なし」を主張するトークンを受け入れていました。それらを拒否し、期待するアルゴリズムを固定しましょう。
これらを理解すれば、JWT は威圧的な文字列から、単純で透明なフォーマット — 読めるクレームを、信頼する前に検証しなければならない署名で守ったもの — になります。
ウェブ & 開発者 をもっと見る
ウェブ & 開発者 のガイドをすべて見る →このガイドで触れたツール