How to Read a JWT (JSON Web Token) — and What to Check
6 min read · Tools-Bench Learn
If you've built or debugged anything with modern authentication, you've met the JWT: a long string with two dots in it, sitting in an Authorization header or a cookie. JSON Web Tokens are how services hand out proof of identity that other services can verify without a database lookup.
The format is deliberately transparent — anyone can read a JWT's contents in seconds. That transparency is a feature, but it surprises developers who assumed tokens were opaque. Here's how to read one, and what to actually look at.
Three parts, two dots
A JWT is three Base64url-encoded segments joined by dots: header.payload.signature. The header is a small JSON object naming the signing algorithm (e.g. "alg": "RS256") and token type. The payload is the interesting part — a JSON object of claims: statements about who the token belongs to and what it permits. The signature is raw cryptographic bytes covering the first two parts.
Because Base64url is an encoding, not encryption, the header and payload are readable by anyone who holds the token — no key required. The signature is what makes the token trustworthy: it proves the contents were issued by whoever holds the signing key and haven't been altered since. Reading a JWT requires nothing; trusting one requires verifying the signature.
The claims that matter
The registered claims you'll see in almost every token:
- sub (subject) — the user or entity the token is about; usually a user ID.
- iss (issuer) — who created the token; a verifier should check this matches the expected auth server.
- aud (audience) — who the token is for; prevents a token minted for one API being replayed against another.
- exp (expiration) — Unix timestamp after which the token is invalid; the claim you check first when debugging.
- iat (issued at) / nbf (not before) — when the token was minted and when it becomes valid.
- Custom claims — roles, permissions, email, tenant IDs; anything the issuer chose to embed.
Debugging with a JWT decoder
The classic debugging scenario: an API returns 401 and you want to know why. Decoding the token answers most cases instantly — the exp timestamp has passed (token expired), the aud doesn't match the API you're calling, the sub isn't the user you thought, or a role claim you expected is missing. All of that is visible without any secret key.
Timestamps are the usual stumbling block: exp and iat are Unix epoch seconds, so "exp": 1783123200 means nothing until converted to a date. A good decoder does the conversion and flags expired tokens for you.
Security caveats worth knowing
Never put secrets in a JWT payload. Tokens transit networks, land in browser storage, and get logged by proxies — and everything in the payload is plaintext to any holder. Personal data, passwords or internal details do not belong there.
Decoding is not verifying. A decoder shows you what a token claims; only signature verification against the issuer's key proves those claims are genuine and untampered. Server code must always verify — and pin the expected algorithm. Historic JWT attacks worked by tricking naive libraries: declaring "alg": "none" (accepting an unsigned token), or swapping an RS256 token to HS256 so the server used its public key as an HMAC secret. Modern libraries defend against both if configured to allow only the algorithms you actually use.
Finally, JWTs are bearer tokens: whoever holds one is whoever it says. That's why they're kept short-lived (minutes to hours, checked via exp) and paired with refresh tokens, and why they must only ever travel over HTTPS.
Decode locally, not on a random website
A real token pasted into a decoder is a live credential — pasting it into a site that sends it to a server hands over a working key to your account or API. Tools-Bench's JWT decoder parses everything in your browser: the token never leaves your device, no request logs see it, and it works offline once the page is open. For production tokens, local-only decoding isn't a nicety; it's the only safe option.
Frequently asked questions
Can someone read my JWT if they intercept it?
The header and payload, yes — trivially, since Base64url is just encoding. What they can't do without the signing key is alter it or forge a new one. Confidentiality in transit comes from HTTPS, not from the token format.
Why did my token stop working?
Nine times out of ten it expired — decode it and compare exp to the current time. Otherwise check that iss and aud match what the API expects, and that the signing keys haven't rotated.
Is it safe to store a JWT in localStorage?
It's debated. localStorage is readable by any script on the page, so an XSS bug leaks the token; an HttpOnly cookie is immune to that but needs CSRF protection instead. Short expiry times limit the damage either way.