Skip to content
← All guidesGUIDE · UPDATED 2026-09-24

Reading JWTs: what decoding shows and what it cannot prove

The three parts of a JSON Web Token, the claims that matter when debugging logins, and why decoding is never verification.

JSON Web Tokens (JWTs) carry identity and permissions between login providers, browsers, and APIs. When a login flow breaks, the first debugging step is usually to look inside the token: has it expired, is the audience right, is the expected role present? Decoding makes that easy. It is just as important to understand what decoding does not tell you.

Three parts, two of them readable

A JWT is three Base64url-encoded parts joined by dots: header.payload.signature. For example:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFkYSIsImlhdCI6MTc5MDAwMTc3NCwiZXhwIjoxNzkwMDA1Mzc0fQ
.<signature>

The JWT decoder turns the first two parts back into JSON:

Header:  {"alg":"HS256","typ":"JWT"}
Payload: {"sub":"1234567890","name":"Ada","iat":1790001774,"exp":1790005374}

and converts the timestamps: issued at 2026-09-21T14:42:54Z, expiring one hour later. The header names the signing algorithm. The payload holds the claims. The signature is binary and is shown only as a byte count.

That the payload is readable by anyone is the first key point: a JWT is encoded, not encrypted. Never put secrets or sensitive personal data in a JWT payload, because anyone who sees the token can read them. Encrypted tokens exist (JWE, with five parts), but most access tokens are plain signed JWTs.

The claims you will meet

  • iss (issuer): who created the token, usually your identity provider’s URL.
  • sub (subject): the user or client the token is about.
  • aud (audience): which API or app should accept it. A token for one API must be rejected by another.
  • exp, nbf, iat: expiry, not-before, and issued-at times, in Unix seconds, not milliseconds.
  • scope, roles, groups: permissions. Names vary between providers.

Debugging with a decoded token

  • 401 right after login? Compare aud with the audience your API expects, and iss with the issuer it trusts.
  • Works, then fails after an hour? Check exp. Access tokens are short-lived by design, and the client should use a refresh token to get a new one.
  • Fails only on some servers? Clock skew. If a server’s clock is ahead, a fresh token can look expired. If it is behind, the token can look not-yet-valid. Allow a small leeway and keep clocks in sync.
  • 403 instead of 401? The token was accepted, but a scope or role is missing. Check the permission claims.

Decoding is not verification

Anyone can create a token with any header and payload, since Base64url is not protection. What makes a JWT trustworthy is the signature, checked with the issuer’s key: a shared secret for HS256, or a public key for RS256 and ES256, usually published at the issuer’s JWKS endpoint. Only your server-side JWT library, configured with the expected algorithm, issuer, and audience, can decide whether a token is valid.

Classic vulnerabilities come from skipping parts of that check:

  • Accepting "alg": "none", which means an unsigned token.
  • Algorithm confusion: letting the token’s header choose the algorithm, so a public RSA key is misused as an HMAC secret.
  • Decoding without verifying, then trusting the claims, which is sometimes done “temporarily” in front-end code.

The decoder on this site deliberately labels every result as unverified and never makes authorization decisions. Use it to read tokens, not to trust them.

Handling tokens safely

A valid access token is a credential: whoever holds it can act as the user until it expires. Prefer test or expired tokens when debugging, and avoid pasting live tokens into online tools that upload data. This decoder runs entirely in your browser and keeps the token only in page memory. If a production token has been exposed, revoke the session.

The underlying encoding is ordinary Base64url. For decoding other Base64 data, or for understanding why - and _ replace + and /, see the encoding guide and the Base64 tool.