DEV Community

Devanshu Biswas
Devanshu Biswas

Posted on

A JWT Decoder in the Browser — and Why the Payload Isn't Secret

That eyJ... string in your Authorization header is a JWT — and anyone can read it. Here's a decoder built on nothing but atob, plus the one security fact every dev needs to know about tokens.

🎫 Paste a token: https://dev48v.infy.uk/solve/day20-jwt-decoder.html

A JWT is three base64url parts

header.payload.signature — split on the dots. The header and payload are base64url-encoded JSON (URL-safe base64: -+, _/, re-pad, then atob + UTF-8 decode). The demo pretty-prints both and humanizes the standard claims (iss, sub, aud, exp, iat, nbf) — including a live "expires in N min / expired" badge.

The security fact

The payload is encoded, not encrypted. Anyone with the token can read every claim — so never put secrets or sensitive PII in a JWT. The signature is the only protection, and it only means something if the server verifies it with the secret/public key. Decoding (what this tool does) ≠ verifying.

Pitfalls worth knowing

  • alg: none and algorithm-confusion attacks — always pin the expected algorithm server-side.
  • JWTs can't be revoked individually → keep them short-lived (use refresh tokens).
  • Clock skew on exp/nbf checks.

🔨 Full build (split → base64url→JSON → claims + exp dates → note: verify server-side) on the page: https://dev48v.infy.uk/solve/day20-jwt-decoder.html

Part of SolveFromZero. 🌐 https://dev48v.infy.uk

Top comments (0)