この記事に関連するツール
ブラウザ上ですぐに試せます。記事の内容を確認しながら使うと、作業の流れをつかみやすくなります。
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 の alg と kid も見ます。
{
"alg": "RS256",
"typ": "JWT",
"kid": "prod-key-2026-05"
}
kid がある場合は、API側が参照するJWKSに同じキーIDが存在するかを確認します。トークンのpayloadが正しく見えても、署名検証に使う公開鍵が環境違いだと認証は通りません。
まず見るポイント
最初に見るのは exp です。
Unix time のままだと判断しにくいので、Unix Time 変換ツールでJSTに直して、期限切れかどうかを確認します。
次に aud と scope を見ます。
API側が期待している audience と違っていたり、必要な権限が入っていなかったりすると、コードが正しくても認証で落ちます。
レビュー前のチェックリスト
expが現在時刻より後になっているiatが不自然に未来になっていないaudが接続先APIと一致しているscopeやroleに必要な権限が入っている- 本番用・検証用のトークンを取り違えていない
この確認を先に済ませるだけで、レビューコメントが「コードの問題」なのか「検証トークンの問題」なのかを分けやすくなります。
実例: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を付けてください」のように具体化できます。