JWT Decoder
Decode JSON Web Tokens — header, payload, signature. Local-only, no tokens leave your browser.
How to Use
- Paste a JWT into the input area. JWTs are three Base64-URL-encoded segments separated by dots (header.payload.signature).
- Header and payload decode live as you type or paste.
- The header shows the algorithm (alg) and token type (typ).
- The payload shows the claims — both standard (iss, sub, exp, etc.) and any custom claims.
- The signature is displayed but not verified — verification requires the signing key, which never leaves your server.
- Watch for the "exp" (expiration) claim — the tool flags expired tokens.
JWT Anatomy
History of the JWT
JSON Web Tokens were standardized as RFC 7519 in May 2015 by Michael Jones, John Bradley, and Nat Sakimura — three of the same people behind the OpenID Connect specification, which was JWT's first major real-world application. The format had been circulating in IETF drafts for several years before that, evolving alongside related specs (JWS, JWE, JWA, JWK) that handle signing, encryption, algorithms, and key formats respectively. The combination is sometimes called the JOSE family of standards.
JWT solved a specific problem: existing session-token formats (opaque random strings looked up server-side) couldn't be used easily across distributed services or single-page applications. JWTs are self-contained — the relying party can verify the signature with a known key and trust the claims directly, without a database lookup. That property made them the dominant token format for OAuth 2.0, OpenID Connect, microservices authentication, and serverless platforms throughout the late 2010s.
JWT's flexibility has also been the source of its problems. Early library bugs accepted "alg":"none" tokens. RSA-vs-HMAC algorithm-confusion attacks have been found in multiple major libraries. Token-revocation is awkward because JWTs are stateless by design. The community response has been better library defaults (always allowlist algorithms), short token lifetimes paired with refresh tokens, and the rise of paseto and other "JWT done right" alternatives. Most production systems today use JWTs successfully — but the format demands more care than the simplicity of the spec suggests.
About This Decoder
This tool decodes the header and payload of a JWT by Base64-URL-decoding each segment and parsing the resulting JSON. The signature segment is shown as raw bytes but is intentionally not verified — verification requires the signing key, which should never leave your server. If you need to verify a token, do it on the backend with a vetted library (jose for Node.js, PyJWT for Python, jjwt for Java, jsonwebtoken for many languages).
Everything runs entirely in your browser. The token you paste is never transmitted to a server, logged, or stored — it's safe to inspect tokens you've pulled from your browser's DevTools or your CLI. Still: a JWT in flight is essentially a password. Treat it accordingly: rotate any token you've shared with a tool you don't fully trust.
Frequently Asked Questions
Does this verify the signature?
No — signature verification requires the signing key (a shared secret for HMAC algorithms or a public key for RSA/ECDSA). This is a decode-only inspection tool. Verification must happen server-side using the appropriate key, and you should never trust a decoded payload from the client.
Is it safe to paste my real production token?
Everything runs client-side using the browser's atob/JSON.parse — nothing is transmitted or logged. That said, treat any active token like a password: don't paste it into web tools you don't trust, don't screenshot it, and rotate it if you think it has been exposed. This tool runs in your browser and works fully offline once loaded.
What are the standard JWT claims?
iss = issuer (who created the token), sub = subject (who the token is about), aud = audience (who the token is for), exp = expiration time (Unix timestamp), nbf = not-before time, iat = issued-at time, jti = JWT ID (unique identifier). Custom claims live alongside these and use whatever names your application picks.
What does "alg":"none" mean and why is it dangerous?
It declares the token has no signature, so any verifier that honors the alg field would accept any payload. This was a famous vulnerability in early JWT libraries. Always configure your verifier with an explicit allowlist of algorithms (e.g., HS256 only, or RS256 only) and reject 'none' unconditionally.
What's the difference between HS256, RS256, and ES256?
HS256 is HMAC with SHA-256 — symmetric, uses a shared secret. RS256 is RSA with SHA-256 — asymmetric, uses a private key to sign and a public key to verify. ES256 is ECDSA on the P-256 curve — also asymmetric but uses much smaller keys for the same security. Use HS256 when both sides share a secret; use RS256 or ES256 when you need to publish the verification key (e.g., third parties verifying your tokens).
Should I store JWTs in localStorage?
Common but risky. localStorage is accessible to any JavaScript on the page, including XSS payloads. HTTP-only cookies are safer because JavaScript can't read them — combine that with SameSite cookies and CSRF protection. JWT-as-cookie also pairs naturally with refresh-token rotation.
Common Use Cases
Debugging an authentication failure
Paste a token your API rejected to see exactly which claim is wrong, expired, or missing.
Inspecting third-party tokens
Decode tokens from Auth0, Okta, Cognito, Firebase, or any other identity provider to see what claims they include.
Verifying expiration timing
Check the 'exp' claim against the current time to confirm a token's lifetime matches your spec.
Building a JWT-based API
Use the decoder to validate that your backend is producing tokens with the expected header, payload structure, and standard claims.
OAuth 2.0 / OIDC debugging
Inspect ID tokens during an OpenID Connect flow to confirm subject, audience, and nonce handling.
Security review
Quickly check whether an issued token is using a strong algorithm (RS256/ES256/HS256) and includes appropriate expiration, issuer, and audience claims.
Last updated: