コンテンツにスキップ

JWT デコーダー

JWT(JSON Web Token)をブラウザ上でデコードし、ヘッダー・ペイロード・署名を可視化します。iat / exp / nbf は日時に自動変換されます。

完全無料 登録不要 ブラウザ完結 5 言語対応 ダークモード

JWT の構造について

JWT は header.payload.signature の3つのパートをドット(.)で連結した文字列です。ヘッダー・ペイロードは Base64URL エンコードされた JSON、署名はヘッダーで指定したアルゴリズム(HS256 / RS256 など)で生成されています。

主要なクレーム: iss(発行者)、sub(主題)、aud(受信者)、exp(有効期限)、nbf(有効開始日時)、iat(発行日時)、jti(JWT ID)

うまく動かない・表示がおかしい場合は お問い合わせフォーム からご報告ください。

📖 つまずきやすいポイント

JWT のヘッダー・ペイロード・署名を分解して表示し、expiat のような時刻のクレームを日時に変換します。処理はブラウザ内で完結し、署名の検証は行いません (鍵が必要なため)。ここで押さえておくべきなのは、「デコードできる」ということは「中身が誰にでも読める」ということだという点です — JWT のペイロードは暗号化されておらず、単に Base64URL で符号化されているだけです。

ケース 何が起きるか どうする
ペイロードに機密を入れてしまう Base64URL は符号化であって暗号化ではありません — このページがそうしているように、鍵を持たない誰でも中身を読めます。それでも「署名されているから安全」という誤解は根強く、ペイロードに個人情報・内部の権限構造・社内 ID・ときにはメールアドレスと生年月日をまとめて入れてしまう設計が見られます。JWT はブラウザの localStorage や Cookie に保存され、ログにも残り、URL に載ることもあります中身は「公開情報として扱われる」と考えるのが正確です。 ペイロードには「識別子」だけを入れ、中身はサーバーで引いてください — ユーザー ID とロール名程度に留め、氏名・メールアドレス・住所は入れません。暗号化が必要なら JWE (JSON Web Encryption) という別の仕様がありますが、その前に「そもそも JWT に入れる必要があるか」を問い直してください — 多くの場合、必要なのは「誰であるか」だけで、「何者であるか」はサーバーが知っていれば十分です。判断の基準は単純で、「その値がアクセスログに平文で出ても構わないか」です — 構わないなら入れてよく、困るなら入れてはいけません。
デコードしただけで中身を信じてしまう 署名を検証しなければ、JWT は「ユーザーが自由に書き換えられる文字列」にすぎません。デコードして role: "admin" を読み、そのまま権限判定に使うコードは、攻撃者が自分でその値を書いたトークンをそのまま受け入れます。歴史的に有名な失敗が 2 つあり、1 つは alg: "none" 攻撃 — ヘッダーのアルゴリズムを none に書き換え、署名を空にすると、それを素直に受け入れる実装があったためです。もう 1 つは HS256 と RS256 の取り違えで、公開鍵を HMAC の共有鍵として使わせることで、公開情報だけで有効な署名を作れてしまいます 検証は必ずライブラリの検証関数で行い、許可するアルゴリズムを明示的に固定してくださいjwt.verify(token, key, { algorithms: ["RS256"] }) のように書きます。この引数を省略すると、ヘッダーの alg を信じる実装があります — 攻撃者が書き換えられる値を、検証の方式の決定に使ってはいけません。デコードだけを行う関数 (jwt.decode のような名前のもの) を認可の判断に使わないでください — 名前が似ているので混同されますが、これは検証を行いません。用途はデバッグ表示だけです。実装を書く前に、そのライブラリの「検証する関数」と「デコードするだけの関数」を必ず確認してください。
ログアウトしたのにトークンが使える JWT はステートレスであることが設計上の利点であり、同時に最大の制約です。サーバーはトークンを保存していないので、発行したトークンを個別に無効化する手段がありません — ログアウトとは実際には「クライアント側でトークンを捨てる」ことにすぎず、そのトークンをコピーして持っていた者は、有効期限まで使い続けられます。同じ理由で、権限を剥奪しても、既に発行済みのトークンには古い権限が書かれたままです。「退職者のアクセスを止めたはずなのに 1 時間使えた」というのはこれです。 有効期限を短くし、リフレッシュトークンと組み合わせてください — アクセストークンは 15 分程度にし、更新にはサーバー側で管理するリフレッシュトークンを使います。この構成なら、リフレッシュトークンを無効化することで最大 15 分で権限が切れます即時の失効が要件なら、ブロックリスト (失効させたトークンの ID を保存し、検証時に照合) が必要ですただしこれはステートを持つということなので、JWT を使う利点の一部を手放すことになります。判断はここが分岐点で — 即時失効が本当に要るなら、素直にセッション ID とサーバーサイドセッションを使うほうが単純で確実です。JWT が向くのは、複数のサービスをまたぐ認証や、検証だけを分散させたい場合です。

時刻のクレームは「秒」です。expiatnbf はいずれも Unix 秒で、ミリ秒を入れると有効期限が 5 万年後になり、実質的に無期限のトークンができあがります — JavaScript の Date.now() がミリ秒を返すため、Date.now() + 3600000 のように書いてそのまま exp に入れる間違いは非常によく起きます (正しくは Math.floor(Date.now() / 1000) + 3600)。デコード結果の日時が遠い未来になっていたら、この間違いを疑ってください — このページが時刻を日時に変換して表示しているのは、まさにそれを目で確認するためです。もう 1 点、サーバー間の時計のずれに備えて、nbfexp の検証には数十秒の許容 (leeway) を設けてください — 主要なライブラリにはそのオプションがあります。最後に運用上の注意として、有効期限内の本番トークンを、外部のオンライン JWT デコーダーに貼らないでくださいそれは認証情報そのものであり、貼った先のサーバーのログに残れば、そのまま他人がなりすませます。このページはブラウザ内で完結しますが、その保証は開発者ツールの Network タブで確認する習慣を持ってください

📖 使い方

  1. 1
    JWT をコピー
    API のレスポンスや Authorization ヘッダから JWT 文字列を取得します。
  2. 2
    入力欄に貼り付け
    ページ上部のテキストエリアに JWT をペーストすると、自動的にデコードが実行されます。
  3. 3
    ヘッダー・ペイロードを確認
    アルゴリズム (alg)・発行者 (iss)・有効期限 (exp) などのクレームを可視化して確認できます。

❓ よくある質問

JWT とは何ですか?
JWT (JSON Web Token) は、Base64URL でエンコードされた header / payload / signature をドットで連結した認証トークンです。主にログイン後の API 認証に使われます。
署名検証はできますか?
このツールはデコード専用です。署名検証には秘密鍵(HS256)または公開鍵(RS256/ES256)が必要なため、別ツール JWT 生成・署名 を使用するか、バックエンドで検証してください。
入力した JWT はサーバーに送信されますか?
送信されません。デコード処理はすべてブラウザの JavaScript で完結しており、ネットワーク通信は発生しません。
exp が期限切れの場合どう対処すれば?
期限切れの JWT は無効です。リフレッシュトークンを使って新しい JWT を取得するか、再ログインしてください。exp はフロント側でも必ず検証しましょう。
🐛 このツールで問題が発生しましたか?

完全無料・登録不要。再現手順だけでも結構です。届いたご報告は運営者に直接届き、修正の参考にします。

※ 不具合再現のため、ブラウザ情報 (UA / 画面サイズ / 言語 / URL) を自動で送信します