Skip to content
ToolsNow
Guides All tools

How to read a JWT (and what the three parts actually do)

A JSON Web Token is three Base64 sections split by dots — readable by anyone, forgeable by no one. How the format works, the claims, and the classic pitfalls.

Published

Open your browser’s developer tools on almost any logged-in web app and you will find a JWT: a long string of letters, digits and exactly two dots. That token is probably what keeps you logged in — and despite appearances, most of it is readable by anyone who holds it.

The shape: three parts, two dots

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 . eyJzdWIiOiIxMjM0In0 . SflKxwRJSMeKKF2QT4fwpM...
        header                             payload                    signature

Each section is Base64url-encoded (a URL-safe Base64 variant using - and _ instead of + and /, with padding dropped). The first two decode to plain JSON. The third is binary — a signature — and does not decode to anything readable, which is correct and expected.

The header says how the token is signed:

{ "alg": "HS256", "typ": "JWT" }

The payload carries the claims — the actual content:

{
  "sub": "user-1234",
  "name": "Jane Doe",
  "iat": 1753487000,
  "exp": 1753490600
}

The signature is computed over the first two sections with a secret (or private key). It is what makes the token trustworthy.

Paste any JWT into the decoder here and both JSON sections appear instantly — it runs locally, which matters, because a real token pasted into a random website is a credential handed to a stranger.

Reading the standard claims

The registered claim names are terse by design (the spec wanted small tokens):

ClaimNameMeaning
ississuerWho created the token
subsubjectWho the token is about — usually the user ID
audaudienceWho it is intended for
expexpirationWhen it stops being valid
iatissued atWhen it was created
nbfnot beforeWhen it starts being valid
jtiJWT IDUnique token identifier

The timestamps are Unix time — seconds since 1 January 1970 UTC. So "exp": 1753490600 is a moment, not a duration; a decoder worth using translates it to a date and tells you whether it has passed. Anything else in the payload (name, role, email…) is a custom claim the issuing application chose to include.

What the signature does and does not do

The signature is the entire security story, and its guarantee is precise: the token was created by someone holding the key, and has not been altered since. Change one character of the payload and the signature no longer matches; without the key, a matching signature cannot be produced.

What the signature does not do is hide anything. The payload is encoded, not encrypted — this trips up developers constantly, and it means: no secrets in JWT payloads, ever. Anyone who obtains the token (browser storage, logs, a shared link) reads every claim. The related distinction between encoding, encryption and hashing is its own article.

Two signing families are common: HS256 (one shared secret both signs and verifies) and RS256/ES256 (a private key signs, a public key verifies — anyone can check validity, only the issuer can mint). Which is in use is right there in the header’s alg field.

Traditional sessions store state on the server; the browser holds only a session ID. JWTs invert this: the server signs a token containing the session data and holds nothing. Any server with the verification key can validate a request without a database lookup — which is why JWTs dominate in APIs, microservices and single sign-on.

The inversion has a famous cost: a JWT cannot be revoked. It is valid until exp, whoever holds it, because there is no server-side record to delete. This is why real systems issue short-lived access tokens (minutes) paired with longer-lived refresh tokens, and why “log out everywhere” features are harder to build than they sound.

Debugging checklist

When a token is rejected, the decoded contents usually explain it:

  1. exp in the past? The overwhelmingly common cause. Check iat too — an implausible issue time means clock skew between servers.
  2. aud mismatch? Tokens for one API get rejected by another.
  3. Wrong alg? A verifier expecting RS256 rejects HS256 tokens.
  4. Not three dot-separated parts? It is not a JWT at all — opaque session tokens and API keys look similar and decode to nothing.

None of these require the signing key to diagnose — which is the practical upside of a format where the envelope is transparent and only the seal is secret.