API連携や管理画面の実装では、JWTそのものよりも「このトークンは今も有効か」「想定した権限が入っているか」「環境を間違えていないか」の確認に時間を使いがちです。
レビュー前にJWTを一度デコードしておくと、認証エラーの原因をかなり早く切り分けられます。

こんな場面で使う

たとえば、検証環境でAPIを叩いたら 401 Unauthorized が返ってきたとします。
実装を疑う前に、JWTの中身を確認します。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

JWTツールに貼り付けると、header と payload を分けて確認できます。

{
  "sub": "user_123",
  "aud": "devtoolkits-api",
  "scope": "articles:read articles:write",
  "iat": 1779001200,
  "exp": 1779004800
}

署名検証まで行う場合は、header の algkid も見ます。

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "prod-key-2026-05"
}

kid がある場合は、API側が参照するJWKSに同じキーIDが存在するかを確認します。トークンのpayloadが正しく見えても、署名検証に使う公開鍵が環境違いだと認証は通りません。

まず見るポイント

最初に見るのは exp です。
Unix time のままだと判断しにくいので、Unix Time 変換ツールでJSTに直して、期限切れかどうかを確認します。

次に audscope を見ます。
API側が期待している audience と違っていたり、必要な権限が入っていなかったりすると、コードが正しくても認証で落ちます。

レビュー前のチェックリスト

  • exp が現在時刻より後になっている
  • iat が不自然に未来になっていない
  • aud が接続先APIと一致している
  • scoperole に必要な権限が入っている
  • 本番用・検証用のトークンを取り違えていない

この確認を先に済ませるだけで、レビューコメントが「コードの問題」なのか「検証トークンの問題」なのかを分けやすくなります。

実例:401と403を切り分ける

APIレビューでよくあるのが、期限切れの 401 Unauthorized と、権限不足の 403 Forbidden を混同するケースです。

{
  "aud": "admin-api",
  "scope": "articles:read",
  "exp": 1779004800
}

このpayloadで記事更新APIを叩いているなら、exp が有効でも articles:write がないため403になる可能性があります。逆に scope が正しくても aud が別API向けなら、認証基盤側で401になることがあります。

JWTを読むときは、期限、接続先、権限を分けて確認すると、レビューコメントも「トークンを更新してください」「write scopeを付けてください」のように具体化できます。

関連ツール