How to use JWT Decoder
What it does & when you need it
You've got a JWT from an Authorization: Bearer header, a cookie, or a login
response, and you need to see what's inside — which user, which scopes, when it
expires — without pasting a production credential into a random website. This
decoder splits the token, Base64URL-decodes the header and payload locally, and
shows the claims plus a human-readable expiry. Nothing is transmitted; the whole
thing runs in your browser.
How to use
- Paste the token into the jwt buffer, or press Sample to load an
example. A JWT has three parts separated by dots:
header.payload.signature. - The decoded header and payload appear as formatted JSON. The
Registered claims panel translates
iat,nbf, andexpinto UTC dates and flags whether the token is expired or not yet valid. - Use Copy payload (or
Ctrl/Cmd+Enter) to copy the claims.
Things worth knowing
Decoding is not verifying — this is the one thing to internalise. A JWT is signed, not encrypted. The payload is just Base64URL-encoded JSON that anyone can read, and decoding it tells you nothing about whether it's authentic. A token with a tampered payload still decodes perfectly here. To trust a token you must verify its signature against the issuer's secret (HS256) or public key (RS256/ES256) — a step this tool deliberately does not perform.
The alg: none attack. RFC 7519
allows an "unsecured" JWT whose header says "alg": "none" and which carries no
signature. Several libraries historically accepted these by default, letting an
attacker forge any payload they liked. The defence is to pin the expected
algorithm when verifying and reject none outright. Because this tool only
decodes, an alg: none token displays without complaint — a useful reminder of
why blind trust is dangerous.
Times are seconds, not milliseconds. exp, iat, and nbf are Unix
timestamps in seconds (per the spec's NumericDate). A frequent bug is passing
Date.now() — which is milliseconds — straight into exp, producing a token
that "expires" tens of thousands of years from now. If your token never seems to
expire, check the magnitude of exp; a 13-digit value is milliseconds and
wrong. A dedicated Unix timestamp converter (coming soon) makes checking these
against a wall-clock date quick.
Claims worth knowing. Beyond timing, watch for iss (issuer), aud
(audience), and sub (subject). A verifier should check that aud matches your
service and iss matches the expected identity provider — a valid signature on a
token minted for a different audience is still not a token for you.
The payload is ordinary JSON, so you can pretty-print it with the JSON formatter; the whole token is Base64URL under the hood.