~/tools/jwt
> jwt decoder
decode json web tokens (jwt) in your browser. split header, payload, and signature; base64url-decode and pretty-print the header and claims. no signature verification — this is a debug tool, not a security check.
decoded client-side. this tool does not verify signatures.
## overview
a jwt is a compact, url-safe string of three base64url-encoded segments joined with dots: header.payload.signature. the header declares the signing algorithm, the payload carries claims (iss, sub, aud, exp, iat, …), and the signature authenticates the header and payload against a secret or key. this decoder splits the three segments and base64url-decodes the header and payload so you can read them. it does not verify the signature — that requires the issuer's public key or shared secret and is a separate concern. use this to inspect what a token contains during development, debug expiry issues, or confirm the iss/aud your backend expects. for production checks, use a jwt library in your own code.
## how to use
- paste the token — paste your jwt (e.g. eyJhbGc…) into the input field. it should be three base64url segments separated by dots.
- read the header — the header shows the signing algorithm (alg) and token type (typ). hs256, rs256, es256, or `none` are the common algs.
- read the claims — the payload shows registered claims like iss, sub, aud, exp, iat, nbf, and custom claims your issuer adds. exp and iat are unix seconds.
- check expiry — convert the exp unix timestamp to a local time to see whether the token is still valid. an expired token has exp in the past.
## examples
$ in
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c# out
{
"header": {"alg": "HS256", "typ": "JWT"},
"payload": {"sub": "1234567890", "name": "John Doe", "iat": 1516239022}
}$ in
eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MTYyMzkwMjJ9.abc# out
{"header": {"alg": "HS256"}, "payload": {"exp": 1516239022}}$ in
not.a.jwt# out
error: segments are not base64url## common mistakes
base64url ≠ base64— jwt segments use base64url (url-safe alphabet, no padding). a standard base64 decoder may fail. this tool handles both.signature not verified— decoding is not verifying. an attacker can change claims and re-encode — the signature only detects that if you check it with the right key. use a library server-side for verification.`alg: none`— some legacy libraries accepted `alg: none` tokens as valid. any real verifier must reject none or enforce an allow-list of expected algorithms.clock skew— exp and iat are unix seconds. allow a small leeway (usually 30-60s) for clock skew between issuer and verifier.token exposure— if you paste a token here, you are exposing its contents to your browser (and this site's javascript). we do not store or transmit tokens, but do not paste live production tokens into any online tool.
## faq
does this verify the signature?
no. signature verification needs the issuer's public key or secret, which we do not have and will not ask for. use a jwt library in your backend for verification.
where does decoding happen?
client-side. the token is base64url-decoded in your browser. it is not sent to our servers or any third party.
what algorithms are supported?
decoding is algorithm-agnostic — the segments are just base64url. the alg claim tells you what was used to sign.
is my token safe to paste?
avoid pasting live production tokens into any online tool. even though this one decodes locally, paste test tokens or regenerate afterward. if in doubt, use `echo $TOKEN | cut -d. -f2 | base64 -d | jq` locally.
what about jwe?
jwe (encrypted jwt) has five segments, not three. this tool decodes jws (the signed form). jwe payloads cannot be read without the decryption key.
can i check expiry?
the decoded payload shows exp as a unix timestamp. a value in the past means the token is expired. a value in the future means it is still valid (unless revoked).
can ai agents call this?
yes. the mcp endpoint at drwho.me/mcp/mcp exposes `jwt_decode` for claude desktop, cursor, windsurf, and any mcp-capable client.