JWT Decoder
Paste any JWT token to decode and inspect its header, payload claims and signature. Timestamps are converted to human-readable dates and expiration is checked automatically. Your token never leaves the browser.
Waiting for token…
Waiting for token…
Waiting for token…
Related Tools
Frequently Asked Questions
What is the difference between decoding a JWT and verifying it?▾
Decoding a JWT just Base64URL-decodes the header and payload — it reads the claims but performs zero cryptographic checks. Anyone can decode any JWT without a secret. Verification confirms the signature using the correct algorithm and key, ensuring the token was issued by a trusted party and hasn't been tampered with. This tool is for debugging and inspection only — your server code must always verify the signature before trusting any claim inside a JWT.
What is the 'alg: none' JWT vulnerability and how does it work?▾
The JWT spec originally allowed "alg": "none" to indicate an unsigned token. Several JWT libraries had bugs where passing alg: none in the header caused them to skip signature verification entirely, accepting any forged token as valid. A 2015 disclosure showed this affected multiple popular libraries across languages. Always configure your JWT library to explicitly whitelist the expected algorithm(s) and reject none — never trust the algorithm specified in the token header without validation.
What is the difference between HS256 and RS256, and when should I use each?▾
HS256 (HMAC-SHA256) uses a single shared secret — the same key signs and verifies the token, so every service that needs to verify tokens must possess the secret. RS256 (RSA-SHA256) uses a private key to sign and a public key to verify — you can distribute the public key freely via a JWKS endpoint so any service can verify tokens without ever seeing the signing key. Use RS256 (or ES256) when multiple independent services need to verify tokens, or when integrating with third-party identity systems.
What causes 'token expired' errors on a freshly issued JWT?▾
The exp claim is a Unix timestamp (seconds since epoch) checked against the validating server's current time. A common cause of unexpected expiry errors is clock skew between the issuing and validating servers — even a 1–2 minute difference will cause a freshly issued token to appear expired. Most JWT libraries allow configuring a 'leeway' (e.g., 60 seconds) to tolerate minor clock drift. A decoded token that looks valid in a browser debugger may still be rejected server-side due to this timing mismatch.
Why do the three parts of a JWT use Base64URL encoding instead of standard Base64?▾
Standard Base64 uses + and / characters, which have special meaning in URLs (+ = space, / = path separator) and would require percent-encoding if the JWT were passed as a URL parameter or cookie. Base64URL (RFC 4648 §5) substitutes - for + and _ for /, and omits the = padding characters, producing a compact token that is safe in HTTP headers, query strings, and cookies without any further encoding. This is why the three dot-separated segments of a JWT never contain those characters.