JWT Decoder
Decode JWT tokens online with our free JWT decoder. Instantly inspect header, payload, signature, expiration, algorithm, and claims. 100% browser-based — your token never leaves your device. No signup, no tracking.
What is a JWT?
A JSON Web Token, or JWT (pronounced 'jot'), is a compact, URL-safe token format for carrying claims between two parties. It is defined in RFC 7519 and is the dominant credential format used by OAuth 2.0 access tokens, OpenID Connect ID tokens, API keys in modern auth providers (Auth0, Okta, Clerk, Supabase, Firebase), and inter-service tokens in microservice architectures.
"JSON Web Token (JWT) is a compact claims representation format intended for space-constrained environments such as HTTP Authorization headers and URI query parameters." — RFC 7519, Section 1
A JWT is three Base64URL-encoded JSON objects joined by dots: header.payload.signature. The header describes how the token is signed (the alg claim — for example, HS256 or RS256 — and the typ claim, usually 'JWT'). The payload carries the claims: registered claims like iss, sub, aud, exp, iat, plus whatever custom claims the issuer needs (role, scope, email, tenant ID). The signature is a cryptographic proof, computed over the header and payload with the issuer's secret or private key, that lets the recipient detect tampering.
Crucially, a JWT is encoded, not encrypted. Anyone with the token can read its payload — decoding is just Base64URL and JSON parsing. The security guarantee comes from the signature: an attacker can read a JWT, but cannot produce a different JWT that passes signature verification without the signing key. That is why JWTs are safe to pass over the network, but unsafe to fill with secrets.
A JWT decoder shows you exactly what a token contains — algorithm, claims, expiration — without touching the signature. It is the fastest way to answer 'is this token expired?', 'what role does this user have?', 'which issuer minted this token?', or 'is this an alg:none token I should reject?'. All decoding in this tool runs locally in your browser, so pasting a live production token is safe.
JWT work often pairs with other developer tools. You may need to decode a Base64URL-wrapped segment when debugging a malformed token, URL-decode an Authorization header after capturing it from a proxy, or convert the exp claim to a human date manually. For a deeper walkthrough of how JWTs are signed, verified, and rotated in production, see our Base64 fundamentals guide — Base64URL is the foundation every JWT is built on.
// Decode a JWT in the browser — header & payload only
function decodeJwt(token) {
const [h, p, s] = token.split('.');
const pad = (seg) => seg + '==='.slice((seg.length + 3) % 4);
const decode = (seg) => JSON.parse(
atob(pad(seg).replace(/-/g, '+').replace(/_/g, '/'))
);
return { header: decode(h), payload: decode(p), signature: s };
}
const { header, payload } = decodeJwt(token);
console.log(header); // → { alg: 'HS256', typ: 'JWT' }
console.log(payload); // → { sub: 'user_123', exp: 1999999999, ... }
// Expiration check
const expired = payload.exp * 1000 < Date.now(); Key Features
Decode JWT Instantly
Paste and watch the JWT decode in real time — header, payload, and signature parsed on the fly. No Decode button, no round-trip to a server.
Expiration Detection
Automatically reads the exp claim and shows a red badge when the token is expired, with the exact expiry date in your local time zone.
Algorithm-Agnostic
Decodes every JWS algorithm — HS256/384/512, RS256/384/512, PS256/384/512, ES256/384/512, EdDSA, and alg:none.
100% Local
Decoding runs in your browser via native atob and JSON.parse. Your token is never uploaded — safe for production credentials.
Claim-Aware Display
Highlights the registered RFC 7519 claims (iat, exp, nbf, iss, aud, sub, jti) so you can spot auth issues at a glance.
One-Click Copy
Copy the header JSON, payload JSON, or raw signature to your clipboard with a single click — perfect for bug reports and tests.
Examples
HS256 Token (Valid)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzEyMyIsIm5hbWUiOiJBbGljZSIsInJvbGUiOiJhZG1pbiIsImlhdCI6MTcxNTAwMDAwMCwiZXhwIjoxOTk5OTk5OTk5fQ.4NhxPjwoZxPNuxG-2C5ugGxaUsUJ0QyskAz7Ymz5Sg0
{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "user_123",
"name": "Alice",
"role": "admin",
"iat": 1715000000,
"exp": 1999999999
} HMAC-SHA256 signed token with a subject, role, and future expiration — the most common JWT setup used for session auth.
RS256 Token (Expired)
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtleS0yMDI1LTAxIn0.eyJpc3MiOiJodHRwczovL2F1dGguZXhhbXBsZS5jb20iLCJhdWQiOiJhcGkuZXhhbXBsZS5jb20iLCJzdWIiOiI5MDA4NzE2NSIsImlhdCI6MTYwMDAwMDAwMCwiZXhwIjoxNjAwMDAzNjAwLCJzY29wZSI6InJlYWQ6dXNlciB3cml0ZTpwb3N0In0.signature_placeholder
{
"alg": "RS256",
"typ": "JWT",
"kid": "key-2025-01"
}
{
"iss": "https://auth.example.com",
"aud": "api.example.com",
"sub": "90087165",
"iat": 1600000000,
"exp": 1600003600,
"scope": "read:user write:post"
} RSA-signed OAuth-style access token — note the kid (key ID) in the header and the exp claim showing the token has already expired.
OIDC ID Token
eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJzdWIiOiIxMTA1MDIyNTExNTU4OTkwNzY2Mzk1IiwiYXpwIjoiY2xpZW50LWlkIiwiYXVkIjoiY2xpZW50LWlkIiwiZW1haWwiOiJhbGljZUBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJpYXQiOjE3MTUwMDAwMDAsImV4cCI6MTk5OTk5OTk5OSwibm9uY2UiOiJhYmMxMjMifQ.signature
{
"alg": "ES256",
"typ": "JWT"
}
{
"iss": "https://accounts.google.com",
"sub": "110502251155899076639",
"azp": "client-id",
"aud": "client-id",
"email": "alice@example.com",
"email_verified": true,
"iat": 1715000000,
"exp": 1999999999,
"nonce": "abc123"
} OpenID Connect ID token with ECDSA signature, email claims, and a nonce for replay protection.
Alg: none Token (Unsigned)
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiJkZWJ1Zy11c2VyIiwiaWF0IjoxNzE1MDAwMDAwfQ.
{
"alg": "none",
"typ": "JWT"
}
{
"sub": "debug-user",
"iat": 1715000000
} Unsigned token with alg:none. Accepting this in production is a classic JWT vulnerability — always reject alg:none server-side.
How to Use
- 1
Paste Your JWT to Decode
Paste the full JWT — including the three dot-separated segments — into the input box. The decoder runs instantly in your browser; you do not need to click a button.
- 2
Read the Decoded Header, Payload & Status
Read the algorithm and token type in the decoded header, the claims in the payload, and the expiration / issued-at chips at the top. An expired token is flagged in red.
- 3
Copy the Decoded Output
Use the Copy button on each panel to copy the decoded header JSON, payload JSON, or raw signature. Your token was never sent anywhere — decoding happened locally in your browser.
Common Errors
Accepting alg:none
An unsigned JWT can be forged by anyone. Never allow alg:none in production — always pass an explicit algorithm list to your verify call.
jwt.verify(token, secret) // library default may allow 'none'
jwt.verify(token, secret, { algorithms: ['RS256'] }) Missing exp Claim
A JWT without exp lives forever. If a token is ever leaked, there is no natural revocation point. Always set an expiration appropriate to the token type.
{ "sub": "user_123", "role": "admin" } // no exp { "sub": "user_123", "role": "admin", "exp": 1715003600 } Storing Secrets in the Payload
JWT payloads are not encrypted — anyone with the token can read them. Never put passwords, API keys, or untruncated PII inside a JWT payload.
{ "sub": "user_123", "password": "hunter2" } { "sub": "user_123", "role": "admin" } // payload stays minimal Common Use Cases
- Decode Authorization Bearer Tokens
- Decode JWT tokens from Authorization: Bearer headers to verify the claims, audience, and expiration your backend is receiving.
- Decode OAuth 2.0 & OIDC Tokens
- Decode access tokens and ID tokens returned from authorization servers (Auth0, Okta, Google, Keycloak) during OAuth 2.0 and OpenID Connect integration.
- Expired Session Diagnosis
- Confirm in one second whether a rejected token is expired, uses the wrong audience, or has a clock-skew problem.
- Key Rotation Checks
- Read the kid (key ID) in the header to verify your JWKS rotation is handing out tokens signed with the expected key.
- Security Reviews
- Spot tokens signed with alg:none, missing exp, or leaking PII in the payload during code review and pentesting.
- Microservice Token Inspection
- Decode service-to-service tokens inside a mesh to see which scopes and subject a downstream call is authorizing.
Technical Details
- RFC 7519 Compliant
- Handles JWS tokens conforming to RFC 7519 (JWT), RFC 7515 (JWS), and RFC 7518 (JWA) — all registered algorithms are supported for decoding.
- Base64URL Decoding
- Uses the URL-safe Base64 alphabet (- and _ instead of + and /) defined in RFC 4648, with padding-tolerant parsing.
- Browser-Native, Zero Dependencies
- Built on the browser's atob, TextDecoder, and JSON.parse — no external libraries, no network calls, no telemetry.
Best Practices
- Never Trust Without Verifying
- A decoder shows claims; it does not prove them. Always verify the signature server-side against the issuer's key before trusting any claim.
- Reject alg:none in Production
- Configure your JWT library with an explicit allowlist of algorithms. Never accept alg:none, and be suspicious of alg mismatches on key rotation.
- Keep Payloads Lean
- Put identifiers and short-lived claims in the JWT; keep bulky data behind an opaque session ID. Large tokens cost bandwidth on every request.
Frequently Asked Questions
How do I decode a JWT token online?
header.payload.signature) — into the decoder above. Decoding happens instantly in your browser: the header and payload are Base64URL-decoded to readable JSON, and the signature is displayed as a raw string. A status row surfaces the signing algorithm, issued-at time, and expiration, so you can spot an expired token at a glance. To decode a JWT manually, split the token on dots, Base64URL-decode the first two segments, and parse them as JSON — anyone with the token can read its claims because the payload is encoded, not encrypted. This decoder is safe to use with production tokens because nothing ever leaves your device: no network request, no logging, no tracking. What is a JWT (JSON Web Token)?
Is my token safe with this JWT decoder?
How does a JWT decoder work?
Can this tool verify a JWT signature?
What are iat, exp, nbf, iss, aud, sub, and jti?
My JWT is expired — why does the decoder still decode it?
What is the difference between JWT, JWS, and JWE?
Why is alg:none dangerous?
alg:none has no signature — anyone can construct one, claiming to be any user. Early JWT libraries accepted alg:none by default, leading to a well-known class of authentication bypasses where an attacker would strip the signature, set alg to none, and forge an admin token. Every mature JWT library now rejects alg:none unless explicitly allowed, and you should never accept it for authenticated requests. This decoder will still show you an alg:none token, because inspecting one during debugging is legitimate — but treat any such token received in production as hostile. Which algorithms does this JWT decoder support?
Should I store JWTs in localStorage or cookies?
How do I decode a JWT in Node.js, Python, or Go?
jsonwebtoken.decode(token) for read-only, jsonwebtoken.verify(token, key) for verification. Python: PyJWT.decode(token, options={'verify_signature': False}) to read, pass a key to verify. Go: jwt.ParseUnverified(token, claims) for read-only, jwt.Parse(token, keyFunc) for verification. In every language, never verify with options={'verify_signature': False} in production code — that is what this web tool does deliberately for debugging, and it is only safe when you are inspecting, not authenticating. What is the maximum size of a JWT?
I pasted my token and got 'Invalid JWT format' — what's wrong?
header.payload.signature. Common causes: (1) you accidentally copied only the payload segment, (2) whitespace or newlines were pasted in the middle, (3) the token was truncated in transit (common with terminal wrapping), (4) the token is a JWE where the format is header.encryptedKey.iv.ciphertext.tag (five segments), or (5) the token was URL-encoded and you need to URL-decode it first. Check the raw value your API returned — most editors show invisible characters on hover. Can I decode a JWT without the secret key?
My JWT works in Postman but my backend rejects it — how do I debug?
HS256 token will fail against a library configured for RS256 only. (4) kid — if you use key rotation, is the key ID in the header present in your JWKS? (5) signature — have you pasted the right secret/public key? This decoder surfaces (1), (2), (3), and (4) in the header and payload views so you can eliminate them quickly. Related Tools
View all tools →MD5 Hash Generator & File Checksum Tool
Security Tools
Generate MD5, SHA-256, SHA-1 & SHA-512 hashes online for free. Hash text or files in your browser, verify checksums and copy results. No signup needed.
Random Password Generator — Customizable, Strong & Secure
Security Tools
Generate strong random passwords instantly — free, 100% in your browser. Customize length & characters, batch up to 50 with entropy analysis.
UUID Generator & Decoder — v1, v4, v5, v7 Batch Mode
Security Tools
Free UUID generator — create v1, v4, v5, v7 UUIDs instantly. Decode & validate any UUID. Batch generate up to 50. No signup, 100% browser-based.
Number Base Converter — Binary, Hex, Decimal & Octal
Conversion Tools
Convert between binary, hex, decimal, octal and any base (2-36) instantly. Free, private — all processing in your browser.
Base64 Decoder & Encoder
Encoding & Formatting
Decode and encode Base64 online for free. Real-time conversion with full UTF-8 and emoji support. 100% private — runs in your browser. No signup needed.
Compress Images Online — JPEG, PNG & WebP
Conversion Tools
Compress JPEG, PNG & WebP up to 80% smaller — in your browser, no upload. Batch 20 images, adjust quality, compare before & after. Free & private.