JWT Decoder & Inspector

Decode a JSON Web Token to inspect its header, claims, expiry times, issuer and signature — with a built-in security check.

Paste any JWT — an access token from an API, an OAuth/OIDC token from your browser's dev tools, a token your backend rejected — and it is split into its three header.payload.signature parts, base64url-decoded, and laid out for inspection: the full header and payload as formatted JSON, a plain-English table of every registered claim (issuer, subject, audience, expiry, not-before, issued-at, jti and more) with each timestamp shown in your local time and UTC, a security findings panel that flags unsigned tokens, weak or unusual algorithms, missing or long-lived expiry, and signature-size mismatches, and the raw signature as a hex dump.

🔒 100% private — nothing is uploaded or stored. Tokens are decoded entirely in your browser with plain JavaScript. A JWT is a credential — the pasted token never touches our servers, is never written to disk, and the page keeps working even if your internet connection drops.
⚠️ Decoding is not verification. Decoding a JWT is a reversible encoding step (base64url), not decryption and not cryptographic checking. The signature segment is shown as raw bytes — this tool does not verify that the signature is valid, was produced by the real issuer, or that the token hasn't been tampered with. Anyone can read these claims, and anyone can craft a token that looks identical. Only the relying party, verifying the signature with the issuer's trusted key, can establish that the token is authentic.

Token (paste the full token, including all three dot-separated parts)

waiting for a token
Decodes live as you type — or press Ctrl+Enter.

How a JWT is built

A JSON Web Token (RFC 7519) is a compact, dot-separated string of three parts:

  • Header — JSON declaring the signing algorithm (alg) and token type (typ, normally "JWT"). It may also carry a kid (key ID) telling the verifier which key to use.
  • Payload — JSON of claims: statements about the token. The registered claims are iss (issuer), sub (subject), aud (audience), exp (expiry), nbf (not before), iat (issued at) and jti (unique ID). OIDC adds userinfo claims like email and name.
  • Signature — a cryptographic signature over base64url(header) + "." + base64url(payload), computed with the issuer's key.

Both JSON parts are encoded with base64url — the URL-safe variant of base64 (uses - and _ instead of + and /, and drops padding). Because base64url is a plain encoding, decoding it reveals the JSON instantly to anyone. That is by design: JWTs carry information, not secrecy.

Decoding is not verification — why that matters

This tool (and every "JWT decoder" you'll find) only reverses the base64url encoding. It does not verify the signature: it cannot tell you whether the token was really issued by the claimed issuer, whether the claims were modified after signing, or whether the signature was produced with the legitimate key.

Verification is the relying party's job: it fetches the issuer's public keys (for asymmetric algorithms, usually from a jwks_uri endpoint), picks the key named by kid, recomputes the signature over the first two segments, and compares it with the third. Only then does it check the claims — that exp is in the future, nbf in the past, and that aud includes itself.

The classic failure this matters for: a server that "decodes and reads the claims" without verifying the signature will happily accept a token an attacker crafted by hand. If you're debugging a token your backend rejected, decode it here to see why (wrong audience? expired? missing claim?) — but trust the claims only after the signature checks out.

Common pitfalls this inspector flags

  • alg: none — an unsigned token. If your service ever accepted one, that's a critical vulnerability: any client can mint tokens freely.
  • Algorithm confusion &mdash> if a server expects RS256 but accepts HS256, an attacker can sign a token with the public key (used as the HMAC secret), because the public key is public. Strictly pin the expected algorithm.
  • Missing exp — a token that never expires can't be revoked by time; keep lifetimes short.
  • Long-lived tokens &mdash> access tokens should be short (minutes); if exp − iat is hours or days, that's a refresh token wearing an access token's clothes.
  • Signature size mismatch &mdash> RS256 signatures are 256 bytes, ES256 is 64, HS256 is 32. A mismatch means the signature wasn't produced by the claimed algorithm.
  • Pasting tokens into public tools &mdash> a JWT is a live credential. This page decodes locally in your browser; anything you paste elsewhere may be logged by that site.

Luke Keam
Thank you for reading. Get in touch
Luke Keam | techgeek.biz