Decoding vs. verifying: not the same operation
This is the single most important distinction with JWTs: decoding the header and payload requires no secret at all — they're just Base64URL-encoded JSON, readable by anyone. Verifying the signature requires the actual signing secret (for HMAC algorithms) or the corresponding public key (for RSA/ECDSA) — without it, you can read every claim but have no way to confirm the token wasn't tampered with or forged. A tool that "decodes" a JWT and shows you its claims is not the same as one that confirms the token is legitimate.
What's actually in a decoded token
// header
{ "alg": "HS256", "typ": "JWT" }
// payload
{ "sub": "1234567890", "name": "John Doe", "role": "admin", "exp": 1735689600 }
Common payload claims worth recognizing: sub (subject — usually the user ID), iat (issued-at timestamp), exp (expiration timestamp), iss (issuer), and aud (audience — who the token is intended for). None of these are enforced by the JWT format itself; it's entirely up to the verifying application to check exp hasn't passed, aud matches, and so on.
Why decoding alone doesn't prove anything
Anyone can take a legitimate-looking JWT, modify the payload (say, changing "role": "user" to "role": "admin"), and produce a new, still perfectly decodable token — decoding it back would happily show the modified claims. The signature is what would catch this: recomputing it from the modified header/payload wouldn't match the original signature unless the attacker also had the signing secret. This is exactly why a security check that only decodes a token, without independently verifying its signature against the expected secret/key, provides no actual security guarantee.
Common mistakes
- Treating "I decoded it and the claims look right" as sufficient verification. Only signature verification (with the correct secret/key) actually confirms the token wasn't tampered with.
- Not checking
expexplicitly. A token can have a perfectly valid signature and still be expired — expiration and signature validity are separate checks. - Assuming a decoded payload is confidential just because you needed a tool to read it. It's Base64-encoded, not encrypted — see the Complete Guide to JWT Tokens for the full explanation.
FAQ
Can I decode a JWT without knowing the signing secret?
Yes — the header and payload are just Base64URL-encoded JSON, readable by anyone; only signature verification requires the secret or key.
Does a successfully decoded JWT mean it's valid?
No — decoding just reads the claims; verifying the signature (and checking exp/aud/etc.) is what actually confirms the token is legitimate and unexpired.
What does the exp claim represent?
The token's expiration time, as a Unix timestamp — the verifying application is responsible for checking this against the current time; it isn't automatically enforced by the token format.
Decode and inspect any JWT's header and payload instantly with the JWT Decoder — entirely client-side, your token never leaves your browser.