JWTs (JSON Web Tokens) power authentication in most modern web and mobile apps, but the actual structure of a JWT β and what's safe to do with one β confuses a lot of developers debugging an auth issue for the first time. Part of our Complete Developer Tools Guide.
The 3 Parts of a JWT
A JWT has the structure header.payload.signature:
- Header β algorithm and token type (e.g. HS256, RS256).
- Payload β claims and data: user ID, expiry, roles, etc.
- Signature β cryptographic proof the token wasn't tampered with, generated using a secret key the server holds.
Decoding β Verifying
This is the single most important point: "decoding" a JWT (reading the header/payload) requires no secret key β anyone can do it, since the payload is only Base64-encoded, not encrypted. But "verifying" a JWT (confirming the signature is valid and the token is genuine, not forged) requires the secret/private key, which only the issuing server has. A decoder tool lets you read a token's contents for debugging β it does not and cannot tell you if the token is cryptographically valid.
Never Put Secret Data in the Payload
Since the payload is just Base64-encoded (readable by anyone holding the token), JWTs should only contain non-sensitive claims (user ID, role, expiry) β never passwords, SSNs, or anything that needs to stay confidential.
Common Debugging Use Case
Check token expiry (exp claim) when debugging "why am I getting logged out" or "why is my API call returning 401" issues. The decoded payload reveals this instantly. Use the JWT Decoder β the payload itself is JSON; see also How to format JSON online free.
Frequently Asked Questions
Can I decode a JWT without the secret key?
Yes β decoding only requires reading the Base64-encoded header and payload, which requires no key. Verifying the signature (confirming the token is genuine) does require the secret/private key.
Is JWT payload data encrypted?
No, it's only Base64-encoded, which is trivially reversible β never put sensitive secret data in a JWT payload, since anyone holding the token can read its contents.
Why does my JWT decoder show valid data even for an expired or invalid token?
A decoder only reads/displays the token's contents β it doesn't check signature validity or expiry against the current time. Always verify expiry (exp claim) and signature server-side, not by visually inspecting a decoded token.
What's the difference between a JWT and a session cookie?
A JWT is self-contained (the server can verify it without a database lookup, since the data and signature travel with the token). A traditional session cookie just holds an ID that the server looks up in a session store.