ログイン後に発行される、ピリオドで区切られた長い文字列。これがJWT(JSON Web Token)です。 中身はBase64でエンコードされたJSONでできており、デコードすれば内容を読むことができます。 本記事では、JWTの構造と、デコードする際に知っておきたい注意点を解説します。
JWTは、ピリオド(.)で区切られた3つの部分からできています。
ヘッダー.ペイロード.署名 eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0IiwibmFtZSI6IuWkqumDjiJ9.xxxxx
| 部分 | 内容 |
|---|---|
| ヘッダー | 署名のアルゴリズムなど、JWT自体の種類を表すJSON |
| ペイロード | ユーザーIDや有効期限など、実際のデータを表すJSON |
| 署名 | ヘッダーとペイロードが改ざんされていないかを検証するための値 |
ヘッダーとペイロードは、それぞれJSONをBase64URLという方式で エンコードしただけのものです。暗号化されているわけではないため、 デコードすれば誰でも中身を読むことができます。
ペイロードをデコードすると、次のようなJSONが現れます。
{
"sub": "1234",
"name": "太郎",
"iat": 1710000000,
"exp": 1710003600
}
subはユーザーを識別するID、iatは発行日時、
expは有効期限を表すことが多く、いずれもUnix時間(秒)で
記録されます。アプリ独自の項目(メールアドレスや権限など)が
含まれている場合もあります。
ここが誤解されやすい点です。JWTのペイロードは暗号化ではなく エンコードなので、第三者が中身を読むことは誰でもできます。 しかし、ペイロードの値を勝手に書き換えて再度エンコードしても、 署名が一致しなくなるため、正規のサーバー側では「改ざんされたトークン」 として拒否されます。
つまり、JWTの安全性は「中身が読めない」ことではなく、 「署名によって書き換えを検出できる」ことで保たれています。 デコードツールで中身を見ることと、署名を検証して正当性を確認することは、 まったく別の処理である点に注意してください。
誰でもデコードして読めることを踏まえると、パスワードやクレジットカード 番号のような機密情報を、そのままペイロードに含めるべきではありません。 ユーザーIDのような識別子にとどめ、機密情報が必要な処理は、 サーバー側でIDをもとに取得する設計にするのが安全です。
expはUnix時間(1970年1月1日からの経過秒数)で記録されています。
人が読める日時に変換しないと、有効期限が過ぎているかどうかが
直感的にわかりません。デコードツールでは、この値を人間が読める
日時に変換して表示してくれると、確認がスムーズになります。
JWTのペイロードは、構造としては通常のJSONと同じです。複雑な ペイロードを見やすく整形したい場合は、 JSONの整形・構文確認 の要領でそのまま扱えます。
JWTは、ヘッダー・ペイロード・署名の3つで構成され、ヘッダーと ペイロードはBase64URLでエンコードされたJSONにすぎません。 誰でもデコードして読めますが、署名があるため、書き換えはサーバー側で 検知されます。機密情報はペイロードに入れない設計を心がけてください。
JWTのデコードは JSON整形ツール から試せます。