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_8

A harmless example, signed with the test secret example-secret. Paste it into the JWT decoder without the spaces.

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

ClaimMeans
subSubject: who the token is about, usually a user ID
issIssuer: who created it
audAudience: who it is meant for
expExpires at, as Unix time in seconds
iatIssued at, Unix seconds
nbfNot 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 .

Try it

Related guides

Newest guides