Skip to content

JWT Decoder

Header

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

Payload

{
  "sub": "user-123",
  "name": "Alice",
  "iat": 1700000000,
  "exp": 1700003600
}
ClaimValueNote
subuser-123
exp17000036002023-11-14T23:13:20.000Z
iat17000000002023-11-14T22:13:20.000Z
⚠ This token's exp is in the past.

Signature

fake-signature-not-verified

Signature is shown raw (base64url) and is never verified. To verify, you'd need the issuer's public key or shared secret — out of scope for a decoder.

Estimates for educational purposes — not financial, medical, or legal advice. See terms.

A JSON Web Token packs three pieces of information into a compact, dot-separated string: a header (which algorithm signed it), a payload (the actual claims about who or what it represents), and a signature (proof that the issuer made it). This tool decodes the first two and surfaces the standard claims with human-readable timestamps.

How a JWT is built

A JWT is three base64url-encoded segments separated by dots:

HEADER.PAYLOAD.SIGNATURE

The header is a small JSON object describing how the token was signed: {"alg":"HS256","typ":"JWT"} is the most common shape.

The payload is a JSON object containing claims. Some claim names are standardised by RFC 7519 (the JWT spec): iss, sub, aud, exp, nbf, iat, jti. Anything else is application-specific.

The signature is computed over the header and payload using the algorithm in alg and a key only the issuer holds. The signature lets a recipient verify the token wasn’t tampered with — but verification requires the key, which is why this tool doesn’t do it.

Example: a typical session token

A token like:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiJ1c2VyLTEyMyIsIm5hbWUiOiJBbGljZSIsImlhdCI6MTcwMDAwMDAwMCwiZXhwIjoxNzAwMDAzNjAwfQ.
fake-signature

decodes to:

  • Header: {"alg":"HS256","typ":"JWT"}
  • Payload: {"sub":"user-123","name":"Alice","iat":1700000000,"exp":1700003600}

The iat (issued at) translates to 2023-11-14T22:13:20Z, and exp to 2023-11-14T23:13:20Z — a one-hour token. The badge tells you whether exp is in the past relative to your local clock.

When to use this

  • Debugging auth flows — see what claims your identity provider is actually putting in the token, vs what your server expects.
  • Inspecting third-party tokensid_token from OIDC, access tokens from SaaS APIs.
  • Quick sanity checks — confirm a token isn’t expired, that aud matches your service, that iss is the right issuer.
  • Educational use — see how the format is built without writing code.

Common mistakes

Treating decode as verification. Decoding a JWT proves nothing about authenticity — anyone can build a token with any claims. A real backend must verify the signature using the issuer’s key before trusting any claim inside.

Pasting tokens into untrusted tools. A JWT often carries personally identifying claims (email, user ID, org membership). This tool runs entirely in your browser, but many online JWT debuggers send the token to a server. Check the network tab before pasting anything sensitive into any web tool.

Confusing JWS and JWE. Both are “JWT” but only JWS (3 segments, signed) is decodable without a key. JWE (5 segments, encrypted) needs the recipient’s private key to read the payload.

Reading exp as milliseconds. Standard claims (exp, iat, nbf) are seconds since epoch, not milliseconds. A timestamp like 1700000000 is November 2023, not January 1970. The tool handles the seconds-to-milliseconds conversion when formatting.

What this tool does not do

It doesn’t verify signatures. Use a server-side library with the appropriate key.

It doesn’t decode JWE (encrypted tokens, 5 segments). Decryption requires the recipient’s private key.

It doesn’t edit or re-sign tokens. A new token must come from the issuer; a tampered token will fail signature verification.

It doesn’t store the token between sessions. Refreshing the page loses the input — by design, so a clipboard token doesn’t accidentally hang around in browser state.

For just the base64url header / payload slices without the JWT semantics, the Base64 encoder / decoder gives raw round-tripping.

Frequently asked questions

Does this verify the signature?

No. Verifying a signature requires the issuer's public key (RS256, ES256) or the shared secret (HS256), neither of which the tool has access to. This is a decoder — it splits the token, decodes the base64url segments, and parses the JSON. If you need verification, do it server-side with your own key material. The signature segment is shown raw so you can copy it for separate verification.

Is my token sent anywhere?

No. All decoding happens in JavaScript inside your browser tab. There is no network request when you paste the token, no logging, no telemetry. You can verify in your browser's devtools Network panel — nothing leaves your device. This matters because tokens often contain personal claims (sub, email, custom org IDs) that should not be pasted into random web tools.

Why does it say 3 segments? My token has 5.

A 5-segment token is a JWE (JSON Web Encryption) — the payload is encrypted, not just signed. Decoding requires the recipient's private key. This tool only handles JWS (signed tokens, 3 segments: header, payload, signature). If you have a JWE, you'll need to decrypt it server-side with the appropriate key before its contents are readable.

What do exp, iat, nbf, sub, iss, aud, jti mean?

Standard claims defined by RFC 7519. `iss` (issuer) — who created the token. `sub` (subject) — who or what it's about. `aud` (audience) — who it's for. `exp` (expiration) — when it stops being valid (Unix epoch seconds). `nbf` (not before) — earliest valid time. `iat` (issued at) — when it was issued. `jti` (JWT ID) — a unique identifier. The tool surfaces these separately and converts the time-based ones to ISO timestamps for human reading.

The 'expired' badge says my token is expired but my server still accepts it. Why?

The badge compares `exp` to your local clock. If your machine clock is wrong, or if the issuing server's clock differs by more than a second, the comparison can disagree with what the issuer actually enforces. Most servers also tolerate a small clock skew (typically 30-60 seconds) on either side of `exp`. Treat the badge as a hint, not as the authoritative answer — your server's time and clock-skew policy are what matters in production.