Ttooleras
🎫

Decode and inspect JSON Web Token (JWT) headers, payloads, and signatures. Free, private — all processing in your browser.

Advertisement

The JWT Decoder parses and displays the contents of JSON Web Tokens (JWTs) — the standardized token format used by OAuth 2.0, OpenID Connect, and most modern authentication systems. Paste any JWT (access token, ID token, refresh token, session token) and instantly see the header, payload (claims), and signature — decoded and pretty-printed. The tool identifies the signing algorithm (HS256, RS256, ES256, EdDSA), highlights standard claims (iss, sub, aud, exp, iat, nbf, jti), and warns about expired tokens, missing claims, or insecure alg: none tokens.

JWTs are everywhere: Google, GitHub, Auth0, AWS Cognito, Firebase, Supabase, Stripe, and thousands of APIs issue JWTs for authentication and authorization. When debugging auth flows, inspecting API errors, investigating security issues, or just understanding what a token contains, you need to decode it quickly — without pasting sensitive credentials into untrusted websites. This decoder runs entirely in your browser using JavaScript — no part of your JWT is sent to any server. Safe for production tokens, API keys, user session tokens, and any other confidential JWTs.

JWT Decoder — key features

Decode JWT instantly

Paste any JWT — header, payload, and signature are decoded and displayed as formatted JSON in real-time.

Standard claims highlighted

Registered claims (iss, sub, aud, exp, iat, nbf, jti) are labeled and annotated. Expiration times are converted to human-readable dates.

Expiration check

Tokens that have expired or are not yet valid are flagged in red. See exactly how long until expiration or how long ago it expired.

Algorithm identification

The signing algorithm (HS256, RS256, ES256, EdDSA, none) is extracted from the header and documented.

Security warnings

Tokens using `alg: none` or weak algorithms are flagged. Missing critical claims (exp, aud) are highlighted.

Copy any section

Copy the decoded header, payload, or signature independently. Useful for debugging API responses and filing support tickets.

Dark mode JSON syntax highlighting

The decoded JSON is colorized for easy scanning — keys, strings, numbers, booleans all stand out.

100% client-side

Tokens never leave your browser. Safe for production access tokens, user sessions, and sensitive credentials.

How to use the JWT Decoder

  1. 1

    Paste the JWT

    Copy the full token (header.payload.signature) and paste it into the input field. Leading/trailing whitespace is trimmed.

  2. 2

    View decoded header

    The algorithm, token type, and any key identifier (kid) appear at the top. Look at `alg` to see how the token is signed.

  3. 3

    Inspect the payload

    All claims are decoded as JSON. Standard claims are explained; custom claims (like user roles, permissions, or app-specific fields) are shown verbatim.

  4. 4

    Check expiration

    The tool calculates whether `exp` is in the past or future and shows the human-readable date/time. Expired tokens are highlighted in red.

  5. 5

    Verify the signature externally

    This decoder cannot verify signatures (requires the issuer's key). Use a JWT library in your language of choice to verify, passing the correct secret (HS*) or public key (RS*/ES*/EdDSA).

Common use cases for the JWT Decoder

Authentication debugging

  • Debug OAuth access tokens: When API calls fail, decode the access token to check which scopes are granted, who issued it, and when it expires.
  • Inspect OpenID Connect ID tokens: Read user identity claims (sub, email, name, picture) from the ID token returned by Google, Microsoft, Auth0, or Okta.
  • Troubleshoot refresh token flows: Refresh tokens are often JWTs with different claims (longer expiration, refresh-specific audience). Decode to verify structure.
  • Validate SSO integrations: SAML/OIDC assertions arrive as JWTs. Inspect the audience, issuer, and user attributes to debug integration issues.

API development

  • Test your own issued tokens: After generating a JWT on your backend, decode it to verify that the claims match what you intended.
  • Debug third-party API responses: Webhooks from Stripe, GitHub, etc. often include signed JWTs in headers — decode to see context.
  • Understand what an auth provider sends: Before writing JWT validation code, decode a few example tokens to see exactly what claims your auth provider includes.
  • Design token claims: Review existing tokens from similar apps to learn conventions for naming custom claims (role, tenant_id, plan, etc.).

Security review

  • Audit for alg: none vulnerability: Some JWT libraries accept `alg: none` tokens — a critical vulnerability allowing forged tokens. Check your tokens use strong algorithms and that your verifier rejects `none`.
  • Check signing algorithm strength: HS256 with a weak secret can be brute-forced. RS256 with a 2048-bit key is secure. ES256 and EdDSA are modern best practices.
  • Inspect claims for PII leaks: JWTs are not encrypted — anyone with the token can read the payload. Ensure you are not putting sensitive data like passwords, SSNs, or private emails in claims.
  • Verify expiration policy: Long-lived access tokens are a security risk. Most APIs should use short expirations (15 minutes to 1 hour) with refresh tokens.

Learning and education

  • Understand JWT structure: Decode example tokens to see how the header, payload, and signature are composed.
  • Compare JWT formats across providers: Decode tokens from different auth providers (Auth0, Firebase, AWS Cognito, Supabase) to see how they structure claims.
  • Debug JWT library integrations: When a JWT library rejects a token, decode it manually to see exactly what structure your library expects.

JWT Decoder — examples

Simple HS256-signed JWT

Standard JWT with user ID and name.

Input
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNzE0NTIxNjAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Output
HEADER: { "alg": "HS256", "typ": "JWT" }
PAYLOAD: { "sub": "1234567890", "name": "Jane Doe", "iat": 1714521600 }
SIGNATURE: (base64url-encoded HMAC-SHA256)

OAuth access token with scopes

Typical token from an OAuth 2.0 authorization server.

Input
eyJhbGciOiJSUzI1NiIsImtpZCI6ImFiYzEyMyJ9.eyJpc3MiOiJodHRwczovL2F1dGguZXhhbXBsZS5jb20iLCJzdWIiOiJ1c2VyXzQyIiwiYXVkIjoiYXBpLmV4YW1wbGUuY29tIiwiZXhwIjoxNzE0NTI1MjAwLCJpYXQiOjE3MTQ1MjE2MDAsInNjb3BlIjoicmVhZDp1c2VyIHdyaXRlOnVzZXIifQ.sig
Output
HEADER: { "alg": "RS256", "kid": "abc123" }
PAYLOAD: {
  "iss": "https://auth.example.com",
  "sub": "user_42",
  "aud": "api.example.com",
  "exp": 1714525200,  ← expires in 1 hour
  "iat": 1714521600,
  "scope": "read:user write:user"
}

Expired token

Token whose exp claim is in the past is flagged.

Input
JWT with exp = 1714521600 (example)
Output
⚠️ EXPIRED
Expired 2 hours ago

Dangerous alg: none token

Unsigned tokens should always be rejected.

Input
eyJhbGciOiJub25lIn0.eyJhZG1pbiI6dHJ1ZX0.
Output
⚠️ SECURITY WARNING: alg "none" means no signature.
Any verifier accepting alg: none is vulnerable to forged tokens.

Firebase / Google ID token

OpenID Connect ID token from Google Identity.

Input
eyJhbGciOiJSUzI1NiIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJzdWIiOiJ1c2VyXzEyMyIsImVtYWlsIjoidXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJuYW1lIjoiSm9obiBEb2UifQ.sig
Output
HEADER: RS256, kid: 123
PAYLOAD: {
  "iss": "https://accounts.google.com",
  "sub": "user_123",
  "email": "user@example.com",
  "email_verified": true,
  "name": "John Doe"
}

Technical details

A JSON Web Token (JWT, pronounced "jot") is a compact, URL-safe, self-contained token format specified in RFC 7519 (2015). JWTs consist of three Base64URL-encoded parts separated by dots:

``
header.payload.signature
``

Example:
``
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIn0.5mhBHqs5_DTLdINd9p5m7ZJ6XD0Xc55kIaCRY5r6HRA
``

Header (decodes to JSON):
``json
{
"alg": "HS256",
"typ": "JWT"
}
``

- alg — signing algorithm (HS256, RS256, ES256, EdDSA, none, etc.)
- typ — always "JWT"
- kid — (optional) key identifier, used to look up the verification key when multiple are in rotation

Payload (the claims, decodes to JSON):
``json
{
"sub": "1234567890",
"name": "Jane Doe",
"iat": 1714521600,
"exp": 1714525200
}
``

Standard registered claims (RFC 7519):

- ississuer — URL or name of the entity that issued the token
- subsubject — the user or entity the token represents (often a user ID)
- audaudience — the recipient(s) intended to accept this token
- expexpiration — Unix timestamp after which the token is invalid
- nbfnot before — Unix timestamp; token is invalid before this time
- iatissued at — Unix timestamp when the token was created
- jtiJWT ID — unique identifier, used to prevent replay attacks

Signature:

The signature is computed over base64url(header) + "." + base64url(payload) using the algorithm specified in the header:

- HS256 / HS384 / HS512 — HMAC with SHA-256/384/512. Symmetric — same secret signs and verifies. Use for single-service systems.
- RS256 / RS384 / RS512 — RSA signature. Asymmetric — private key signs, public key verifies. Use for multi-service or public APIs.
- ES256 / ES384 / ES512 — ECDSA signature using P-256, P-384, or P-521 curves. Like RSA but shorter keys and faster.
- EdDSA (Ed25519, Ed448) — modern elliptic curve signatures. Best option for new systems.
- none — no signature. A critical vulnerability — tokens with alg: none should always be rejected by verifiers.

This decoder does not verify signatures — verification requires the signing key, which only the issuer has. For signature verification, use a language-specific JWT library (jsonwebtoken, PyJWT, jose) with the correct public key.

Common problems and solutions

JWTs are NOT encrypted

The payload of a standard JWT is Base64-encoded, not encrypted. Anyone with the token can read all claims. **Never put passwords, SSNs, credit card numbers, or other secrets in a JWT payload.** For encrypted tokens, use JWE (JSON Web Encryption) instead of standard JWT.

alg: none vulnerability

Some JWT libraries historically accepted tokens with `"alg": "none"` — meaning no signature is required. An attacker can craft a token with arbitrary claims and no signature. **Always reject `alg: none` tokens** in your verifier. Modern libraries do this by default; verify your version.

Confused-deputy attack (algorithm switching)

A token signed with RS256 (asymmetric) can be crafted to appear signed with HS256 (symmetric, using the public key as the HMAC secret). **Always specify allowed algorithms explicitly** — do not let the token header dictate the verification method.

Missing or ignored exp claim

Without an expiration claim, a token is valid forever. A leaked long-lived token is a major security risk. Always include `exp` and always verify it (most libraries do this automatically).

Storing JWT in localStorage

localStorage is accessible to any JavaScript on the page — XSS can steal tokens. Prefer `httpOnly` cookies for session tokens (with `SameSite=Strict` or `Lax`, and `Secure`) so JavaScript cannot read them. For single-page apps, consider short-lived access tokens with refresh via cookie.

Relying on JWT size limits

JWTs travel in HTTP headers, which have size limits (typically 8 KB total). Large payloads cause requests to fail mysteriously. Keep JWT payloads small — do not stuff user profile data into access tokens. Store large data server-side, reference it with a key in the token.

Stateless revocation

JWTs are self-validating — if a token is compromised, you cannot easily revoke it (you would have to reject by jti or blacklist). Use short expirations (15-60 minutes) and a refresh token flow to limit damage from a leaked access token.

Not rotating signing keys

If a signing key is ever compromised, every token signed with it is forgeable. Rotate keys periodically, use the `kid` header to identify which key signed each token, and serve public keys at a `/.well-known/jwks.json` endpoint so clients can refresh verification keys.

JWT Decoder — comparisons and alternatives

JWT vs session cookies: Session cookies store a random session ID; the server looks up session data in a database or cache. JWTs are self-contained — the token carries all the user data. JWTs are stateless (no database lookup per request), scaling better for multi-server deployments. Sessions are easier to revoke and smaller in size. For single-service applications, session cookies are often simpler. For distributed systems, JWTs reduce coupling.

JWT (JWS) vs JWE: JWS (JSON Web Signature) is the standard signed JWT — payload visible to anyone, integrity guaranteed by signature. JWE (JSON Web Encryption) adds encryption — payload is hidden from intermediaries. Use JWS for authentication; JWE when the token contains sensitive data that must not be readable by clients.

HS256 vs RS256 vs ES256: HS256 (HMAC-SHA256) is symmetric — same secret signs and verifies. Fastest, simplest. Only use when all signers and verifiers are trusted (single-service, small team). RS256 (RSA) is asymmetric — private key signs, public key verifies. Use for public APIs where verifiers should not be able to sign. ES256 (ECDSA P-256) is like RS256 but much shorter keys (256-bit vs 2048-bit) and faster. Prefer ES256 for new deployments.

JWT vs opaque tokens: Opaque tokens are random strings (e.g., abc123...); the server must query a database to validate and retrieve user info. JWTs encode user info in the token itself. Opaque tokens are smaller and easier to revoke; JWTs are faster to validate and self-contained. OAuth 2.0 supports both as access token formats.

JWT vs PASETO: PASETO (Platform-Agnostic Security Tokens) is a modern alternative to JWT designed to fix JWT pitfalls: no alg flexibility (each version has one algorithm), no confusion between signed and unsigned tokens. Smaller adoption than JWT but favored by security experts. If you start fresh in 2026, consider PASETO.

Frequently asked questions about the JWT Decoder

What is a JWT (JSON Web Token)?

A JWT is a compact, URL-safe token format (RFC 7519) used for authentication and authorization. It consists of three parts — header, payload, and signature — separated by dots and Base64URL-encoded. JWTs contain user identity and permissions, signed cryptographically so the server can verify the token without querying a database. Used by OAuth 2.0, OpenID Connect, and most modern APIs.

Is this JWT decoder safe to use with real production tokens?

Yes. The decoder runs entirely in your browser using JavaScript. Your token is parsed client-side — nothing is sent to any server. Open your browser's DevTools Network tab to confirm there are no outbound requests when you decode. Safe for access tokens, ID tokens, refresh tokens, and any other JWT you need to inspect.

Can this tool verify JWT signatures?

No. Signature verification requires the signing key (secret for HS256, public key for RS256/ES256), which only the issuer has. This tool decodes the token content but does not validate the signature. To verify, use a JWT library in your backend language (jsonwebtoken, jose, PyJWT, etc.) with the correct key from the issuer's JWKS endpoint.

What does each JWT section contain?

Header — describes the token (algorithm, type, key ID). Payload — contains the claims (who the user is, what they can do, when the token expires). Signature — cryptographic proof that the token was issued by the authorized party and has not been tampered with. The first two sections are Base64URL-encoded JSON; the third is binary signature data, also Base64URL-encoded.

What are the standard JWT claims?

iss (issuer) — who issued the token. sub (subject) — who the token is about (usually user ID). aud (audience) — who the token is for. exp (expiration) — when the token becomes invalid (Unix timestamp). iat (issued at) — when the token was created. nbf (not before) — the earliest time the token is valid. jti (JWT ID) — unique identifier for replay prevention. Defined in RFC 7519.

Why is alg: none dangerous?

alg: none means no signature. A token with no signature can be crafted by anyone. If a verifier accepts alg: none tokens, an attacker can create a token claiming to be anyone (like an admin) and the server will accept it. Famous CVE: CVE-2015-9235. Always configure your JWT library to reject none and only accept a specific algorithm.

What algorithm should my JWTs use?

ES256 is the modern best choice — asymmetric, short keys, fast signing/verification. EdDSA (Ed25519) is even better if your library supports it. RS256 is traditional and widely supported. HS256 is fine for single-service systems where you do not need asymmetric verification. Avoid MD5, SHA-1, and especially none.

How long should JWT expiration be?

Access tokens: 15 minutes to 1 hour. Short enough that a leaked token is not a big deal, long enough that users do not re-authenticate constantly. Refresh tokens: days to months (but store securely and allow revocation). ID tokens: minutes to hours. Session tokens in single-page apps: 15-60 minutes with automatic refresh.

Can JWTs be revoked?

Not easily. JWTs are stateless — you cannot "invalidate" a token by deleting it from a database. Workarounds: (1) Short expiration — compromised tokens naturally expire. (2) Blacklist — maintain a list of revoked jti values, check on every request (reduces JWT's stateless benefit). (3) Rotate signing keys — invalidates all tokens at once. For high-security use cases where revocation matters, opaque tokens with a database may be a better fit.

Can I put any data in a JWT payload?

Yes, but with caveats: (1) JWTs are not encrypted — anyone with the token can read the payload. Do not include passwords, SSNs, or secrets. (2) Keep them small — JWTs travel in HTTP headers, which have size limits. Do not stuff user profile data into access tokens. (3) Use standard claim names (iss, sub, aud, exp) for interoperability. Custom claims should be namespaced to avoid collisions.

Additional resources

Advertisement

Learn more

Explore more tools

200+ free tools that run in your browser.

Browse all tools →