A JSON Web Token (JWT) looks like opaque random text, but most of it is just Base64URL-encoded JSON that anyone can read. This guide walks through what a JWT contains, how to decode it by hand or with a tool, and the crucial difference between decoding and verifying.
What a JWT looks like
A JWT is three short strings joined by periods: header.payload.signature. The header describes how the token was signed (for example HS256), the payload holds the claims such as sub, name, iat and exp, and the signature is what lets a server trust the first two parts.
Each of the first two parts is JSON that has been Base64URL-encoded, not encrypted. That is why you can decode a JWT without any key.
Decoding the header and payload
Split the token on the periods, take the first two segments, and Base64URL-decode each one. The result is readable JSON. The elci.dev JWT decoder does this automatically and pretty-prints the two objects side by side.
If the decoded payload shows values like iat (issued-at) and exp (expires-at), remember they are Unix timestamps — you can paste them into a timestamp converter to see the actual dates.
Decoding is not the same as verifying
Decoding only reads the token. Verifying means checking the signature against the issuer's secret or public key to confirm nobody tampered with it. A decoder intentionally does not verify, because it has no key.
A token with a valid-looking payload can still be forged if its signature is not checked, so never trust the contents of a JWT just because they decoded successfully.
What to watch out for
JWTs frequently carry sensitive claims, and the payload is readable by anyone who gets hold of the token. Avoid pasting production tokens into third-party tools as a general practice, and never put secrets like passwords or API keys in a JWT payload.