Decoding vs Verifying a JWT

Updated 2026-08-31 · 3 min read

Two different operations

A JWT is three base64url segments separated by dots: header.payload.signature. Decoding just base64-decodes the first two segments — anyone holding the token can do it, no key required. Verifying recomputes the signature over header.payload with a secret or public key and compares it.

That distinction is the single most common source of auth bugs: a decoded token tells you what it claims, never that the claim is true.

Worked example

Take a token whose payload decodes to:

Claims worth checking every time

After signature verification, validate the registered claims — a valid signature on an expired or foreign token is still a rejection:

When a decoder is the right tool

Use a decoder for debugging: checking why an API returned 401, confirming which scopes a provider issued, reading an exp that looks wrong, or comparing the claims two environments produce. It is the fastest way to see whether the problem is the token or your validation code.

Never use decoding as an authorisation step in server code. Libraries make the mistake easy — jwt.decode() skips the signature, jwt.verify() does not.

Algorithm pitfalls

Two classic vulnerabilities come from trusting the token's own header. alg: none asks the verifier to accept an unsigned token. Algorithm confusion swaps RS256 for HS256 so the public key gets used as an HMAC secret. In both cases the fix is the same: pin the accepted algorithm list in your verification call instead of reading it from the header.

Prefer asymmetric signing (RS256/ES256) whenever a token is verified by more than one service, so only the issuer holds a signing key.

Storage and lifetime

Keep access tokens short-lived — minutes, not days — and pair them with a refresh token stored in an httpOnly cookie. JWTs cannot be revoked once issued, so a long expiry means a stolen token stays valid until it lapses. If you need instant revocation, keep a server-side deny list keyed by jti.

Decode a token safely

Paste a token into the JWT Decoder — header, payload and expiry are parsed entirely in your browser, so production tokens are never transmitted. Pair it with the Base64 Decoder when you need to inspect a single segment by hand.

Try the JWT Decoder →Decode a JWT online to read its header, payload claims and expiry status. Free JWT decoder that runs 100% in your browser — tokens are never uploaded.

Frequently asked questions

Is a JWT encrypted?

No. A standard JWS token is only signed, so its payload is readable by anyone. Use JWE, or simply keep secrets out of the payload.

Can I verify a JWT in the browser?

You can verify a signature with a public key, but the check is meaningless for authorisation — the client can skip it. Verify on the server.

Why does my token fail verification after a deploy?

Usually a rotated signing key or a different issuer per environment. Decode the token and compare its iss and kid values.

More guides

How to Decode a JWT SafelyLearn what is inside a JSON Web Token, how to decode the header and payload, how to read exp and iat claims, and why decoding is not verification.HTML Entities and EscapingLearn when to escape HTML, which characters need entities, how encoding helps prevent XSS, and when decoding HTML entities is safe.How to Convert JSON to CSVConvert JSON arrays and objects into CSV for spreadsheets, databases, and reports, including headers, nested values, and escaping rules.URL Encoding Query ParametersLearn why URLs need percent encoding, which characters break query strings, and when to use encodeURIComponent instead of encodeURI.