How JSON Web Tokens Work — and How to Read One Safely
A JSON Web Token (JWT) is the string of three dot-separated chunks you see in Authorization headers and login flows. It looks cryptic, but its design is simple and worth understanding: a JWT carries a small set of claims about a user or session, plus a signature that lets a server trust those claims without a database lookup. This guide explains each part, what the signature does, and how to inspect a token safely.
The three parts of a token
A JWT is three Base64URL-encoded segments joined by dots: header.payload.signature. The first two parts are just JSON that has been encoded so it survives transport in a URL or header — they are not encrypted. Anyone holding the token can decode and read them. The third part, the signature, is what makes the token trustworthy.
The header describes how the token is signed, for example {"alg":"HS256","typ":"JWT"}. The payload holds the claims — the actual data — such as the subject (sub), an expiry timestamp (exp), and any custom fields your application adds.
Encoded is not encrypted
This is the single most important thing to understand about JWTs: the header and payload are encoded, not encrypted. Base64URL is reversible by anyone — it is a transport format, not a security measure. If you put a password, an API key, or personal data in a JWT payload, you have effectively published it to every client and proxy that touches the token.
Only ever place data in a payload that you are comfortable being readable: a user ID, roles, an expiry, an issuer. Treat the token as a sealed envelope whose contents are visible through the paper — sealed against tampering, but not against reading.
What the signature proves
The signature is computed over the header and payload using a secret or a private key. When a server receives a token, it recomputes the signature with the key it holds and compares. If they match, two things are true: the token was issued by someone who knows the key, and the payload has not been altered since. Change a single character in the payload and the signature no longer verifies.
With a symmetric algorithm like HS256, the same secret signs and verifies, so it must stay on the server. With an asymmetric algorithm like RS256, a private key signs and a public key verifies — useful when many services need to validate tokens but only one should issue them.
Common security mistakes
Most JWT vulnerabilities come from skipping verification, not from breaking the cryptography. The classic failures are well documented and easy to avoid:
- Trusting a token without verifying its signature — decoding the payload and acting on it as if it were authentic.
- Accepting alg: none, an old footgun where a token declares it has no signature and a careless library believes it.
- Not checking the exp (expiry) claim, so revoked or stale tokens keep working forever.
- Confusing algorithms: verifying an attacker-supplied RS256 token using the public key as if it were an HS256 secret.
- Putting sensitive data in the payload, forgetting it is world-readable.
How to inspect a token safely
When debugging, you often want to read what a token claims — its expiry, its subject, its roles — without verifying it. The safe way to do this is locally. A decoder that runs entirely in your browser never transmits the token anywhere, which matters because a real access token is a live credential: paste it into a careless online tool and you may have handed your session to a third-party server.
iNNkie's JWT decoder is fully client-side. It splits the token, Base64URL-decodes the header and payload, and shows the claims and timestamps without ever sending the token over the network. Use it to confirm what is inside a token; use your server's key to confirm whether the token is genuine.
Put it into practice
Try the JWT Decoder
Frequently Asked Questions
Can I trust the data in a JWT just by decoding it?
No. Decoding only reveals what the token claims. Without verifying the signature against the issuer's key, you cannot know the token is authentic or unaltered. Decoding is for inspection; verification is for trust.
Is it safe to paste a JWT into an online decoder?
Only if the decoder runs entirely in your browser and never sends the token to a server. A real token is a live credential. iNNkie's decoder processes everything client-side, so the token never leaves your machine.
Why is my JWT rejected even though it decodes fine?
Decoding succeeds for any well-formed token, but a server rejects it if the signature does not verify with its key, if the token has expired (exp), or if claims like the audience or issuer do not match what the server expects.