Programming tool

JWT Decoder

Inspect a JWT's header, payload, and registered claims locally—without claiming verification.

Decoding a JWT does not verify its signature.

Signature

—

What happens when you paste in a token

The decoder splits the input on its periods and requires exactly three sections — a header, a payload, and a signature. Each of the first two is checked against the Base64URL character set (letters, digits, - and _), converted to standard Base64 by swapping those two characters back and padding the string to a multiple of four, then run through atob() and a strict UTF-8 decoder before being parsed as JSON. 'Strict' matters here: if a token has been truncated or corrupted, the decoder throws an error instead of silently returning garbled text.

The header and payload are then pretty-printed with two-space indentation, and any of the seven registered claims defined by the JWT spec — iss, sub, aud, exp, nbf, iat, jti — that appear in the payload are pulled out into a labeled list. The signature itself is never decoded or checked; it's only reported as present or missing.

Reading the three parts

JWT = Base64URL(header) + "." + Base64URL(payload) + "." + signature

The header is usually a small object like {"alg":"HS256","typ":"JWT"} that names the signing algorithm and token type. The payload carries whatever claims the issuer chose to include — standard ones like exp (expiration) and custom ones like a user ID or role list. The signature is a cryptographic value computed over the first two parts using a secret or private key; producing or checking it requires that key, which this page never asks for.

Base64URL is Base64 with two substitutions: - replaces + and _ replaces /, and trailing = padding is dropped. That swap exists purely so the encoded string can sit safely inside a URL query parameter or an HTTP header without needing extra escaping.

Decoding a token is not the same as trusting it

The header and payload of a signed JWT (a JWS) are only encoded, never encrypted, so anyone who intercepts a token — including this page — can read its claims with nothing more than a Base64URL decoder. That is expected behavior, not a flaw: JWTs are designed to be readable, with the signature providing integrity rather than secrecy.

Because of that, decoding a token proves nothing about whether it's genuine. A modified payload, a stripped signature, or a header claiming "alg":"none" will all decode without error here, since verification is a separate step requiring the issuer's secret or public key that a real backend performs — never a client-side viewer. If a token's third segment is empty, it decodes as an unsecured token and this page reports the signature as missing rather than pretending it's valid.

Encrypted tokens (JWE) are a different format with five dot-separated segments instead of three, and their payload genuinely can't be read without the decryption key — this tool only handles the signed, plaintext-payload JWS format.

When this is useful

Typical situations where pasting a token in here saves time:

  • Checking whether an API call is failing because a token's exp claim has already passed, without doing epoch-to-date math by hand
  • Confirming which scopes or roles an OAuth access token actually carries during a third-party API integration
  • Verifying an OpenID Connect ID token's iss and aud match the identity provider and client ID your app expects
  • Spot-checking a token your own backend just issued before handing it to a frontend or mobile client
  • Teaching or learning the three-part JWT structure without spinning up any server tooling
  • Comparing two tokens' claims side by side while debugging a permissions or session bug

Frequently asked questions

Does this tool verify the JWT's signature?

No, and it never will — the decoder only reports whether a non-empty signature segment is present, labeled 'Present (not verified)'. Verifying a signature requires the issuer's secret or public key, which should never be typed into a shared browser tool.

Can I read a JWT's claims without knowing the signing key?

Yes. The header and payload of a standard signed JWT (a JWS) are Base64URL-encoded JSON, not encrypted, so no key is needed to read them — only to prove they haven't been tampered with.

What does 'Missing / unsecured token' mean in the result?

It means the token's third segment was empty, which the JWT spec calls an unsecured token (commonly paired with "alg":"none" in the header). A real verifier is required to reject these; this decoder just reports the missing signature rather than treating the token as valid.

Why do exp, nbf, and iat show two different-looking values?

Those three claims are stored as NumericDate — seconds since the Unix epoch. The decoder shows the raw number alongside the equivalent UTC date it computed from it, so 1735689600 is displayed as 1735689600 (2025-01-01T00:00:00.000Z).

Is a JWT the same thing as a JWE?

No. A JWT most often refers to a JWS (JSON Web Signature) with three dot-separated parts and a readable payload, which is what this tool decodes. A JWE (JSON Web Encryption) has five parts and its payload is genuinely encrypted, unreadable without the decryption key.

Where does the decoding actually happen?

Entirely inside your browser, using the built-in atob() and TextDecoder APIs. The token text is never sent to a server, written to a log, or stored after you navigate away from the page.