How to Decode a JWT Token: Header, Payload & Claims Explained
JWTs are in almost every modern login flow — tucked into cookies, HTTP headers, or localStorage. Most developers use them for months before understanding what's actually in them. This guide breaks down the three parts of a JWT, what each claim means, and the security rules you can't afford to skip.
What a JWT Looks Like
A JSON Web Token (JWT) is a compact, self-contained token defined in RFC 7519. It looks like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cCount the dots — there are two. A JWT always has exactly three Base64url-encoded segments separated by .:
HEADER . PAYLOAD . SIGNATUREThe header and payload are just JSON encoded as Base64url. Anyone can decode them. The signature is different — it's a cryptographic hash that can only be verified with the server's secret key.
Part 1: The Header
The header tells you what type of token it is and which algorithm was used to sign it:
{
"alg": "HS256", // signing algorithm
"typ": "JWT"
}Common alg values: HS256 (HMAC + SHA-256, uses a shared secret), RS256 (RSA + SHA-256, uses a public/private key pair), ES256 (ECDSA + SHA-256). The algorithm determines how the signature is created — and how it's verified.
Part 2: The Payload (Claims)
The payload is where the actual data lives. It's a JSON object containing claims — statements about the user and the token itself.
There are three types of claims:
- Registered claims — standard short-name claims defined by the JWT spec (see table below)
- Public claims — standard names like
emailornamefrom the IANA JWT Claims Registry - Private claims — custom claims your app defines, like
role,org_id, orpermissions
| Claim | Full name | What it means |
|---|---|---|
| iss | Issuer | Who issued the token (usually your auth server URL) |
| sub | Subject | Who the token is about — typically a user ID |
| aud | Audience | Who should accept this token (your API, a client ID) |
| exp | Expiration Time | Unix timestamp after which the token is invalid |
| nbf | Not Before | Unix timestamp before which the token is invalid |
| iat | Issued At | Unix timestamp when the token was issued |
| jti | JWT ID | Unique token ID — used to prevent replay attacks |
Part 3: The Signature
The signature is computed by the server using the header, payload, and a secret key:
HMACSHA256(
base64url(header) + "." + base64url(payload),
secret
)You can't decode the signature — it's a one-way cryptographic hash, not encoded data. Its only job is to prove the token hasn't been tampered with. Without the server's secret key, you can't verify it or forge a new one.
How to Decode a JWT Online
The free JWT Decoder on MyWebUtils splits the token at the dots and decodes the header and payload into readable JSON instantly:
- Paste the token — the tool handles the rest
- Timestamps (
exp,iat,nbf) are shown as both Unix timestamps and human-readable dates - The signature is displayed but cannot be verified without the server's secret — the tool shows you the raw bytes only
- Nothing is sent to any server — everything runs in your browser
Security Rules You Actually Need to Follow
Decoding is not verifying
This is the most important thing in this entire guide. Decoding a JWT shows you its contents. It does not tell you whether the token is legitimate. Anyone can create a JWT with any payload and Base64url-encode it. The signature is what proves it came from your server — and you can only check the signature server-side with the secret key. Never trust decoded JWT claims on the client.
Always check exp
A valid signature doesn't mean the token is still active. Always check that the current time is before the exp timestamp. An expired token must be rejected even if the signature is valid. This is a separate check from signature verification — you need both.
Watch out for the "none" algorithm attack
Some older JWT libraries accepted tokens with "alg": "none" — meaning no signature required. This is a critical vulnerability. Always configure your library to require an explicit algorithm and explicitly reject none.
Keep tokens short-lived
JWTs are stateless — once issued, they can't be revoked before expiry without maintaining a server-side blocklist. Set short expvalues (15–60 minutes for access tokens) and use refresh tokens for longer sessions. The shorter the token lifetime, the smaller the window if a token is stolen.
Frequently Asked Questions
Can I read a JWT without the secret key?
The header and payload — yes, they're just Base64url-encoded JSON. Anyone can decode them. The signature is a one-way hash that requires the secret to verify. This is why sensitive data (passwords, card numbers) should never go in a JWT payload.
What's the difference between JWT and session cookies?
Session cookies store a session ID on the server — every request requires a database lookup. JWTs are stateless — the server embeds everything it needs in the token itself, so there's no database call. The trade-off: JWTs can't be instantly revoked without extra infrastructure. Sessions can be invalidated immediately by deleting them from the database.
How do I decode a JWT in JavaScript?
const payload = JSON.parse(atob(token.split('.')[1]));That works for reading the payload. For production code — where you also need to verify the signature — use a library like jsonwebtoken (Node.js) or jose (browser + Node). Never skip signature verification in backend code.