How to read a JWT, and why decoding is not verifying
A JWT looks like noise, but two thirds of it is plain JSON anyone can read. Here is how to look inside one without leaking it.
The three parts
eyJhbGciOiJIUzI1NiJ9 . eyJzdWIiOiIxMjMiLCJleHAiOjE3MDAwMDAwMDB9 . xun_3-kRmHezN42smd_YJ_QCb5S_kfXZplI_TJMd4_8A harmless example, signed with the test secret example-secret. Paste it into the JWT decoder without the spaces.
- Header: which algorithm signed it, e.g.
{"alg":"HS256"}. - Payload: the claims, e.g.
{"sub":"123","exp":1700000000}. - Signature: a cryptographic check over the first two parts, made with a secret or private key.
Base64URL is just Base64 with - and _ instead of + and /, and no padding. That is why every JWT starts with eyJ: it is {" encoded.
The claims you will see
| Claim | Means |
|---|---|
| sub | Subject: who the token is about, usually a user ID |
| iss | Issuer: who created it |
| aud | Audience: who it is meant for |
| exp | Expires at, as Unix time in seconds |
| iat | Issued at, Unix seconds |
| nbf | Not valid before, Unix seconds |
The times are seconds since 1 January 1970 UTC; the Unix time converter turns them into dates, and the JWT decoder does it for you and says whether the token has expired.
Decoding is not verifying
Anyone holding a JWT can read its payload, so never put secrets in one. And anyone can make a token with any payload they like; what they cannot do without the key is make a valid signature. A server must verify the signature, check exp, and only accept the algorithms it expects. Accepting "alg":"none", or letting the token choose its algorithm, has caused real security holes.
Do not paste live tokens into just any site
A valid access token is as good as a password until it expires. Many online decoders send what you paste to their server. Tooltern's decoder runs entirely in your browser, but the safest habit is still to use expired or test tokens when you can.
Deciding where to keep the token: localStorage vs cookies.
Related
How to revoke a JWT before it expires
Questions
Can anyone decode a JWT?
Yes. The header and payload are only encoded, not encrypted, so anyone with the token can read them. Encrypted tokens (JWE) exist but look different: five parts instead of three.
Does a JWT decoder need the secret?
No, reading the contents needs no key. The secret or public key is only needed to verify the signature.
Why does my JWT say expired when it was just issued?
Usually a clock difference between machines, or exp written in milliseconds instead of seconds. JWT times are seconds.
Published · updated .