JWT デコード
デコードのみで、署名は検証しません——そのため、token が有効かどうかの判断には使わず、中身の確認だけに使ってください。
JWT は header.payload.signature から成ります。前の 2 つは Base64URL でエンコードされた JSON(可読)で、3 つ目は署名です。ここでは前の 2 つだけをデコードするので、鍵がないと署名を検証できません。
使う場面
- API が 401 を返したとき、まず exp が過ぎていないか、iat が手元の時計と何分ずれているかを確認し、単純な期限切れの可能性を潰してからコードを触りたい場面。
- サーバが実際にどのクレームを出しているか(scope、roles、aud、独自フィールド)や、ヘッダの alg と kid を確認したいとき。ドキュメントを読みながら名前を推測するより速いです。
使わないほうがよい場面
- トークンが本物か、改ざんされていないかを判断したい場合。デコードは Base64URL を戻すだけで、ペイロードを書き換えて貼り直せます。サーバ側で秘密鍵または JWKS の公開鍵による署名検証が必須です。
- デコードした roles や scope をフロント側の権限判定に使いたい場合。これらのクレームは未検証で、1 文字変えれば権限昇格になります。認可はサーバが検証した後に行い、画面側は導線を隠すだけにとどめます。
デコードはブラウザ内で完結し、トークンは送信も記録もされません。制限:署名の検証は行わず、alg、iss、aud、失効状態も確認しません。3 分割の JWS のみ対応で、JWE(5 分割の暗号化トークン)は扱えません。有効期限は端末の時計で計算するためずれる場合があります。本番トークンは信頼できるページでのみ扱ってください。
よくある質問
JWT をここに貼っても安全ですか?
概ね安全ですが、条件があります。デコードはページの JavaScript 内で完結し、送信も記録も外部リクエストもなく、再読み込みで消えます。リスクはページの外にあります。ブラウザ拡張、注入された第三者スクリプト、共用 PC のクリップボードや履歴からはトークンが見えます。本番のアクセストークンはパスワード相当なので、可能な限りテスト環境の偽トークンで調査してください。どうしても実際のトークンを扱う場合は、ページの出所を確認し、終わったらクリアしてください。
署名を検証しないなら、この結果は何に使えますか?
中身を読むためだけに使えます。構造、クレーム、時刻の確認です。誰が発行したか、失効していないか、偽造されていないかは証明できません。許可・認可・復号といった判断は、サーバが署名を検証し exp、nbf、iss、aud を確認した後に行う必要があります。ここに表示される「有効」は、手元の時計で 1 回引き算した結果にすぎず、サーバが受け入れる保証はありません。
exp はまだ先なのに API が 401 を返すのはなぜ?
よくある原因は 4 つです。端末の時計が数分ずれていて nbf や exp の境界で落ちる。サーバがトークンを失効させた、または鍵をローテーションした(JWT はステートレスなので、失効は拒否リストか短い有効期限でしか実現できません)。aud や iss の不一致、またはトークン種別の取り違え(id_token を access_token として使う)。ゲートウェイと業務サービスの時刻不一致。デコードで切り分けられるのは時計に関わるものだけです。