コンテンツへスキップ
🚀 10件のツールが公開中、ずっと無料 — ツールボックスは成長を続けます
ホーム›ブログ›JWT 解説: JSON Web Token のデコードとデバッグ
ガイド

JWT 解説: JSON Web Token のデコードとデバッグ

JSON Web Token の実際の中身、漏らさずにブラウザーでデコードする方法、API が受け入れるかを決めるクレーム、デコードが検証ではない理由、そして誰でも読めるペイロードに秘密を入れてしまう失敗について。

✍ 執筆:創業者兼CEO(BuildToolForge チーム)🗓 2026-10-17⏱ 12分
jwtjson web tokenauthenticationclaimsapi security
セキュリティツールガイド2026

JWT
まるわかり

JSON Web Token の中身

ヘッダー · ペイロード · 署名

jwt · decode
$ decode eyJhbGciOiJIUzI1NiJ9...
header{"alg":"HS256"}
payload{"sub":"1234"}
exp1799884800
✓ ブラウザ内でデコード · 署名は検証されない
標準クレーム
iss
発行者
sub
サブジェクト
aud
オーディエンス
exp
有効期限
nbf
開始時刻
iat
発行時刻
ブラウザでデコードすべてのクレームを読む期限切れを見抜くデコードは検証ではない

JWT とは実際のところ何なのか

JSON Web Tokenは文字列です。仕掛けはそれだけです。クライアントにセッション ID を渡してセッション自体はサーバーに置く、という方法の代わりに、署名された言明 —「これはユーザー 4821 で、権限はこれ、14:05 に失効する」— を渡し、それを持ち歩かせます。署名鍵を信頼するサービスは、データベースに問い合わせることなくその言明を読み、処理を進められます。

便利さと危うさは同じ理由から来ています。データがクライアントの手元にあるということです。発行したトークンは、持っている人なら誰でも読めます。失効するまで取り消せません。そして署名を信頼するものすべてがそれを受け入れます。本番環境での JWT の問題は、ほとんどがこの三つのうちどれかを忘れたところから生まれます。

トークンはドットで区切られた 3 つの意味不明な塊に見えます。

eyJhbGciOiJIUzI1NiIsImtpZCI6ImtleS0yIn0.eyJzdWIiOiI0ODIxIiwiZXhwIjoxNzY1MTExMTExfQ.3xS7_c9Nn-aQ

暗号化はされていません。最初の 2 つの塊は Base64url の素の JSON です。これは URL で安全に使える文字セットで、+と/を-と_に置き換え、末尾の=パディングを落とします。誰でも一瞬で JSON に戻せます。それがまさにJWT デコーダーのしていることです。

3 つの部分とそれぞれの役目

ドットで分けると、ヘッダー、ペイロード、署名になります。

ヘッダー

小さく、そしてほとんどが鍵の話です。algは署名アルゴリズムの名前、typは通常JWT、kidは鍵 ID で、発行者が複数の鍵を持つときに検証側がどの公開鍵を取ってくるべきかを示します。鍵のローテーション後にトークンが突然検証に通らなくなったら、まずkidを見てください。

ペイロード

クレーム、つまり実際に主張されている内容です。一部は仕様で登録済みのもの(iss、sub、aud、exp、nbf、iat、jti)で、残りは発行者が入れると決めたもの、たとえばscope、roles、tenant_id、メールアドレス、機能フラグなどです。

署名

最初の 2 つの部分に対する MAC または電子署名で、文字列に現れているそのままの形を対象にします。この点は重要です。署名が覆っているのはエンコード済みのバイト列なので、JSON を再シリアライズして再エンコードすると、データが同じでも検証に通らないトークンになります。「整えるため」にトークンを作り直すことは絶対にしないでください。

トークンのデコード手順と、最初に見るところ

ドットを含めた文字列全体をデコーダーに貼り付けます。リクエストからコピーした場合はBearerの接頭辞を外してください。外してくれるツールを使っても構いません。そのうえで、次の順に読みます。

  1. そもそもデコードできたか。各部分が正しい Base64url の JSON ではないとデコーダーが言うなら、トークンは途中で切れたか壊れて届いています。サイズ上限に達した Cookie も、行が折り返されたヘッダーも、こう見えます。
  2. exp。「5 分前は動いていた」という報告の大半は失効で説明できます。最初に切り分けるべき項目です。
  3. audとiss。別の宛先向けに発行されたトークンは、まったく正当なトークンであり、API が拒否するのは正しい動作です。
  4. 独自クレーム。scopeの中身が期待どおりかを議論する価値が出るのは、標準クレームが通ってからです。

できる限りローカルでデコードしてください。トークンは有効な資格情報です。適当なサイトに貼り付けるのは、パスワードを貼り付けるのと同じ種類の失敗です。使う価値のあるツールはブラウザー内でデコードし、どこにも送信しません。

トークンが通るかどうかを決めるクレーム

仕事のほとんどは 5 つのクレームが担っており、そのどれか一つだけでもリクエストを拒否できます。

  • exp — 失効時刻。秒単位の Unix タイムスタンプです。ここにミリ秒の値を入れるのは定番のバグで、57000 年あたりに着地してトークンが永遠に失効しなくなります。よいデコーダーは実際の日付と、どれだけ前に過ぎたかの両方を出します。
  • nbf — 開始時刻。この時刻までトークンは無効です。意図して使うことは少なく、時計が進んだマシンで誤って設定されることがあります。
  • iat — 発行時刻。形式上は失効していないが不自然に古いトークンを拒否するのに使えます。iatが未来を指していれば時計の問題に気づけます。
  • aud — 宛先。この検査を省く API は、自社の別サービスが自分向けに発行したトークンも喜んで受け入れてしまいます。マイクロサービス間の権限昇格の実際の経路です。
  • iss — 発行者。期待する発行者を厳密に固定し、鍵はその発行者が公開している鍵セットからのみ取得します。

jtiは少し毛色が違い、そのトークン固有の ID です。保存して照合しなければ意味を持ちませんが、特定の 1 本だけを失効させられるのはこのクレームのおかげです。

デコードは検証ではありません

ここでつまずく人が多いところです。デコードは Base64url を読んで JSON を見せます。トークンが何を言っているかはわかります。その言明が正しいかどうかは、何もわかりません。

誰でも{"sub":"1","role":"admin"}と書いて Base64url にし、末尾に適当な文字列を署名のふりで付けて渡せます。それはどのデコーダーでも、当サイトのものでも、問題なくデコードされます。通用させないのは検証の段階です。発行者の鍵で署名を再計算し、一致しなければトークンを拒否する。この段階には秘密鍵か公開鍵が必要で、場所はあなたのサーバーであり、ブラウザー上のツールが代わりに行うことはできません。

ですからデコーダーは計測値の表示として扱い、証拠としては扱わないでください。「デコードしたら admin と書いてあった」はセキュリティ上の指摘になりません。「サーバーで検証したうえで admin だった」は指摘になります。

正しそうなトークンが 401 を返される理由

トークンがきれいにデコードできるのに API が受け付けない場合、原因はほぼ次のどれかです。

  • 失効している。expは自分の時計ではなくサーバーの時計と比べてください。
  • 時計のずれ。2 分進んだサーバーは、発行されたばかりのトークンまで拒否します。多くのライブラリーがわずかな猶予を許しているのはこのためで、猶予が 0 に設定されているなら見直す価値があります。
  • 宛先が違う。1 つの ID プロバイダーが複数の API を相手にしているときによく起きます。
  • 鍵のローテーション。発行者は新しい鍵で署名したのに、検証側は古い鍵セットをキャッシュしたままで、kidが解決できなくなっています。
  • そもそも届いていない。Authorizationヘッダーの欠落や形式の崩れ、Cookie の消失、ヘッダーを落とすプロキシーなどです。トークンを疑う前に、サーバーが実際に何を受け取ったかを確認してください。HTTP ステータスコード検索とステータスコードのガイドは、401 と、まったく別の意味を持つ 403 を見分けるのに役立ちます。

401 か 403 か

401は資格情報が欠けている、失効している、または検証できないという意味です。直す対象はトークンです。403は資格情報に問題はなく、それでも答えは「いいえ」という意味です。直す対象は権限、あるいはscopeクレームです。認可の失敗に 401 を返すサービスは、はじめから原因ではなかったトークンの調査に人を送り込むことになります。

署名アルゴリズムの選び方と確認

実務で問題になるのは 2 系統です。HS256は共有秘密鍵を使う HMAC で、検証できる者は署名もできます。1 つのサービス内なら問題ありませんが、組織をまたぐ用途には向きません。RS256とES256は秘密鍵で署名し公開鍵で検証するため、API は自分では発行できないトークンを検証できます。

そしてalg: noneがあります。仕様が許している未署名のトークンで、決して受け入れてはならないものです。標準にあるということはライブラリーにもあったということで、つまり悪用されてきました。アルゴリズムをトークン自身のヘッダーから取る検証側には、「これは未署名だからそのまま信用せよ」と告げられてしまいます。関連する手口として、RS256 の検証側に、公開鍵を HMAC の秘密鍵として署名した HS256 トークンを渡すものもあります。

防ぎ方は方針を 1 行決めることです。トークンを見る前に、受け入れるアルゴリズムを決めておく。それ以外は拒否します。ヘッダーはどの鍵を使うかのヒントであって、署名を検証するかどうかの指示ではありません。デコーダーがalg: noneを赤で警告するのはこのためです。

ペイロードに決して入れてはいけないもの

ペイロードは暗号化ではなくエンコードなので、どのクレームもトークンを持つ人には公開されています。しかもトークンはブラウザーのストレージ、ログ、エラートラッカー、サポートチケット、スクリーンショットにまで行き渡ります。ペイロードから外しておくべきものは次のとおりです。

  • URL に書かないようなもの全般。パスワード、API キー、カード番号、健康に関する情報。
  • 公開したくない内部の識別子。データベースの主キー、内部ホスト名、ライセンス条件など。
  • 大きな塊。トークンはすべてのリクエストに付いていきます。1 キロバイトのクレームは 1 回ごとに 1 キロバイトであり、肥大したトークンはプロキシーのヘッダーサイズ上限に当たる確実な方法です。

トークンを URL に置かないことも大切です。クエリー文字列に入れたトークンは、サーバーのログ、Refererヘッダー、ブラウザーの履歴に残ります。Authorizationヘッダーで送り、サイトが適切なReferrer-Policyを設定しているか確かめてください。セキュリティヘッダーのガイドでその点を扱っていますし、セキュリティヘッダーチェッカーで今送っている内容がわかります。

失効、リフレッシュ、そして失効取り消しの難しさ

JWT は呼び戻せません。いったん発行されればexpまで有効で、背後のアカウントに何が起きても変わりません。ユーザーを無効化しても、そのアクセストークンは期限が来るまで動き続けます。リクエストごとにデータベースを見ないことの代価です。

定石は 2 本のトークンです。短命のアクセストークンは、日ではなく分の単位で、クレームを運んで実務をこなします。長命のリフレッシュトークンはサーバー側に保存し、使われるたびにデータベースと照合し、必要なら即座に失効させられます。ログアウトとは、リフレッシュトークンを無効化し、アクセストークンが自然に死ぬまでの短い時間を待つことになります。

失効までの時間は意識して決めてください。それは、アクセスを取り消してから実際にアクセスが止まるまでの差です。15 分はよくある妥協点です。時間単位は正当化しにくく、日単位は失効取り消しが事実上ないという意味になります。即時の失効が必要ならjtiの拒否リストを持つことになりますが、そうなるとまたリクエストごとにストアを参照しており、素直なセッションのほうが単純な設計かもしれません。

どれを選んでも、調査の手順は同じです。トークンをデコードし、expとaudを読み、時計を確認し、そのうえでサーバーで署名を検証する。この順に 4 段階、そしてトークンの問題はほとんどが最初の 2 段階で正体を見せます。

関連ツールとガイド:

よくある質問

秘密鍵がなくても JWT をデコードできますか。⌄

できます。ヘッダーとペイロードは Base64url でエンコードされているだけで暗号化されていないため、トークンを持つ人は誰でも読めます。鍵が必要なのは署名の検証だけです。だからこそ、ペイロードに機密データを入れてはいけません。

オンラインのデコーダーに JWT を貼り付けても安全ですか。⌄

デコードがブラウザー内で行われる場合に限ります。トークンは失効するまで有効な資格情報なので、サーバーへ送るツールはあなたの資格情報を扱っていることになります。当サイトのデコーダーはページ内で完結し、トークンをどこにも送りませんが、できるかぎり失効済みやテスト用のトークンを使うのが最も安全な習慣です。

トークンは正常にデコードできるのに 401 が返るのはなぜですか。⌄

デコードできることは、文字列の形式が正しいことしか示しません。よくある原因は、すでに過ぎた exp、発行者と検証側の時計のずれ、別の API を指す aud、鍵のローテーション後に検証側が解決できない kid です。

JWT とセッション Cookie の違いは何ですか。⌄

セッション Cookie はポインターです。サーバーが状態を持ち、リクエストごとに参照するため、即座に失効させられます。JWT は状態そのものを運ぶので参照は不要ですが、失効時刻より前に取り消すことはできません。JWT はサービスをまたぐ規模に向き、セッションは制御しやすさに向きます。

HS256 と RS256 のどちらを使うべきですか。⌄

HS256 は 1 つの秘密鍵を共有するため、検証できる者は署名もできます。単一のサービス内であれば許容できます。RS256 と ES256 は秘密鍵で署名し公開鍵で検証するので、関係する当事者が 2 者以上になればこちらが適切です。いずれにしても、受け入れるアルゴリズムは検証側で固定し、トークンの alg の値を信用しないでください。

著者について
創業者兼CEO、BuildToolForge
X でフォロー: @Buildtoolforge

Web 開発とセキュリティに 15 年以上携わってきた実務経験を持つ。実践的な Web セキュリティ、つまりサイトを安全・確実に保ち、トラブルを素早く解決できるようにすることに注力。BuildToolForge は、こうしたチェックを無料で、プライベートに、わかりやすく行えるようにするためのサイトです。ツールは可能な限りブラウザ内で動作し、ツールに入力した内容は保存されません。

ガイドの書き方: すべてのガイドは実務経験をもとに執筆し、公式の標準と照らし合わせ、実際のドメインで自社ツールを使って検証しています。標準やツールが変わればガイドも更新します。誤りを見つけたら contact@buildtoolforge.com までお知らせください。

最終更新日:2026年11月2日