JWT Decoder — Decode & Inspect JWT Tokens

Decode JWT tokens in real time. Header, Payload, and Signature displayed with color coding. Expiry check included.

Do not paste sensitive tokens from production systems.
JWT Token
JWT Structure
History
No history yet.

About JWT Decoder — Decode & Inspect JWT Tokens

JWT Decoder decodes JSON Web Tokens and displays the header and payload in formatted JSON, letting you inspect claims such as expiration time, issuer, and subject instantly. It is a vital debugging tool for developers working with authentication systems.

How to Use

  1. 1Paste your JWT token into the "JWT Token" input field.
  2. 2Select the output format — "Formatted JSON" or "Split by section".
  3. 3Click "Decode JWT" to see the decoded header and payload.

Features

  • Instantly reveals JWT header algorithm and type
  • Decodes payload claims including exp, iat, sub, and custom fields
  • Split view separates header, payload, and signature sections
  • Completely client-side — your token is never sent to a server
01

JWT Structure and How It Works

JSON Web Tokens are a compact, URL-safe format for transmitting claims between parties. Understanding the three-part structure helps you decode and debug tokens effectively.

Header, Payload, and Signature Explained

A JWT consists of three Base64URL-encoded parts separated by dots: header.payload.signature. The header is a JSON object specifying the token type and the signing algorithm — typically {"alg": "HS256", "typ": "JWT"} or {"alg": "RS256"} for asymmetric tokens. The payload is the main content: a JSON object containing claims, which are statements about an entity (usually the user) and metadata. The signature is computed by encoding the header and payload, then signing with a secret (HMAC) or private key (RSA/ECDSA). This signature ensures the token has not been tampered with — but it does not encrypt the payload. Anyone can read the header and payload without the secret key, which is why sensitive data should never be placed in a JWT payload unless the token is also encrypted (JWE).

Standard Claims (RFC 7519)

The JWT specification (RFC 7519) defines a set of registered claim names that have well-known meanings. The "iss" (issuer) claim identifies who created the token — typically a domain or service name. The "sub" (subject) claim identifies the principal the token represents, often a user ID. The "aud" (audience) claim specifies the recipient the token is intended for. The "exp" (expiration time) claim is a Unix timestamp after which the token must be rejected — always check this when debugging authentication failures. The "iat" (issued at) claim records when the token was created. The "nbf" (not before) claim specifies a time before which the token must not be accepted. In addition to these registered claims, applications routinely add custom claims such as roles, permissions, email, and tenant IDs.

02

Debugging Authentication with JWT Decoder

JWT decoding is an essential debugging skill for developers working with OAuth2, OpenID Connect, and custom authentication systems. These patterns cover the most common debugging scenarios.

Diagnosing Token Expiration and Claims Issues

The most common JWT-related bugs are expired tokens and missing or incorrect claims. When a user reports being unexpectedly logged out or receiving 401 Unauthorized responses, decode the token and check the "exp" claim first. Convert the Unix timestamp to a human-readable date using the Unix Timestamp Converter — if it is in the past, the token has expired and the client needs to refresh it. For authorization bugs where users cannot access resources they should have access to, inspect the roles or permissions claims to verify the correct values are present. Mismatched "aud" claims are another common issue — if the token was issued for one service but sent to another, the receiving service will reject it.

Algorithm Confusion and Security Considerations

The "alg" field in the JWT header specifies the signing algorithm. HS256 uses a shared secret (HMAC-SHA256) and is common for single-service tokens. RS256 and ES256 use public/private key pairs, allowing the public key to be distributed for verification without exposing the signing secret — preferred for multi-service architectures. A critical security vulnerability known as "algorithm confusion" occurs when a server accepts tokens signed with "alg": "none" or switches from RS256 to HS256 using the public key as the HMAC secret. Always explicitly whitelist accepted algorithms server-side and never allow "none". Remember: decoding a JWT shows you its contents, but only server-side verification with the correct key confirms authenticity.

FAQ

Does this tool verify the JWT signature?
No. This tool only decodes the header and payload. Signature verification requires the secret key and should be done server-side.
Is it safe to paste a JWT here?
The tool runs entirely in your browser and no data is transmitted. However, avoid pasting production tokens into any online tool as a security best practice.
What claims are commonly found in a JWT payload?
Common claims include "sub" (subject), "iat" (issued at), "exp" (expiration), "iss" (issuer), and "aud" (audience).
Can I modify a JWT payload with this tool?
This tool is a decoder only — it reads and displays the JWT content but cannot re-sign tokens. Modifying a JWT payload without the secret key produces an invalid signature that will be rejected by any server that verifies JWTs. To create or modify JWTs, use a JWT generator tool or your application's server-side JWT library (e.g., jsonwebtoken for Node.js, PyJWT for Python).
What does "alg: none" in a JWT header mean?
An "alg: none" JWT has no cryptographic signature. Any server that accepts "alg: none" tokens is vulnerable to a critical security flaw, as an attacker can craft arbitrary tokens with any payload. RFC 7518 designates "none" as a valid algorithm for unsecured JWTs, but production authentication systems must explicitly reject them. If you see "alg: none" tokens in a security audit, treat it as a high-severity finding.

Found a bug or something not working as expected?

Report a bug →