JWT Decode Explained: How to Read a Token Payload Safely
Developers search jwt decode when an API returns 401, when claims look wrong in the client, or when they inherit a token from a colleague and need to see what is inside. Decoding is straightforward. Knowing what not to do with the result is the important part.
JWT structure in 30 seconds
A JSON Web Token is three Base64Url segments separated by dots:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.SIGNATURE
│ Header │ Payload │ Signature │
| Part | Contents |
|---|---|
| Header | Algorithm (alg) and type (typ), usually {"alg":"HS256","typ":"JWT"} |
| Payload | Claims: sub, exp, iat, custom roles, etc. |
| Signature | HMAC or asymmetric signature over header.payload |
Decoding = Base64Url-decode header and payload to JSON.
Verifying = recompute signature with secret/public key and compare.
Decoding does not require the secret. Verifying does.
Example decode
Payload segment decoded:
{
"sub": "user_8f3a",
"name": "Alex",
"role": "editor",
"exp": 1735689600
}
sub— subject (user ID)exp— expiry as Unix timestamp- Custom claims like
roleare app-defined
If exp is in the past, the token is expired regardless of what the UI shows.
Decode vs encryption
JWTs are signed, not encrypted, in the common JWS form. Our Japanese guide compares encoding vs encryption:
| Encoding (JWT payload) | Encryption | |
|---|---|---|
| Who can read? | Anyone with the token | Only holders of the key |
| Purpose | Transport format | Confidentiality |
Do not put passwords, credit card numbers, or PII you would not show in a URL into a JWT payload.
Safe workflow for debugging
-
Get the token — Network tab → request →
Authorization: Bearer eyJ...or fromlocalStorage/ cookie (know your app’s storage). -
Decode locally — Use JWT Decode tool in the browser. Processing stays on your machine.
-
Read claims — Check
exp,iss(issuer),aud(audience), and app-specific fields. -
Fix the right layer — Wrong role? Issuance bug. Expired? Refresh flow. Signature invalid on server? Wrong secret or tampered payload.
-
Revoke if leaked — If you pasted a production token into an untrusted site, rotate keys and invalidate sessions.
What attackers can and cannot do
Can: Decode payload, see claims, modify payload and re-encode (without valid signature).
Cannot (without secret/key): Produce a valid signature the server will accept.
So: never authorize actions from payload alone on the client. Always verify on the server (or API gateway).
Common algorithms
| alg | Type | Verify with |
|---|---|---|
| HS256 | HMAC | Shared secret |
| RS256 | RSA | Public key (private key signs) |
| ES256 | ECDSA | Public key |
Header alg: none attacks are why libraries must reject unsigned tokens. Use maintained JWT libraries — do not hand-roll signature verification.
jwt decode vs jwt verify in code
// Decode only (no trust) — e.g. jwt-decode library
import jwtDecode from 'jwt-decode';
const payload = jwtDecode(token);
// Verify (trust) — server side
import { verify } from 'jsonwebtoken';
const payload = verify(token, process.env.JWT_SECRET);
Client apps decode for display. APIs verify before trusting.
Online tools: privacy checklist
- Does the token leave your browser? (Network tab → check requests)
- Is the site HTTPS?
- Is the token already expired or from a test environment?
When in doubt, local tools win.