Décodeur JWT

Décodez les tokens JWT localement dans votre navigateur pour inspecter en-têtes et claims

What is a JSON Web Token (JWT)?

A JSON Web Token (JWT) is a compact, URL-safe token format defined in RFC 7519 that represents claims between two parties. JWTs are the dominant bearer token format in modern web authentication — used by OAuth 2.0 access tokens, OpenID Connect ID tokens, and custom authorization schemes across millions of APIs. A JWT encodes a JSON object as a sequence of three Base64URL-encoded segments separated by dots: header.payload.signature.

This decoder parses and inspects JWT tokens entirely client-side, extracting the header and payload without performing signature verification. Decoding a JWT does not validate its authenticity — it reveals the token's content for debugging, claim inspection, and development workflows. For signature validation, use a dedicated JWT verifier tool that checks the cryptographic signature against the issuer's public key or shared secret.

JWT Structure: Header, Payload, and Signature

Every JWT consists of exactly three parts separated by period (.) characters. Each part is independently Base64URL-encoded (RFC 4648 §5) — a URL-safe variant of Base64 that replaces + with -, / with _, and omits padding = characters. Decoding a JWT means reversing this Base64URL encoding on the first two segments to reveal their JSON content.

  • Header (JOSE Header): A JSON object declaring the token type ("typ": "JWT") and the signing algorithm ("alg": "RS256", "HS256", "ES256", etc.). For JWS tokens signed with asymmetric keys, the header often includes a "kid" (Key ID) field that identifies which public key from the issuer's JWKS endpoint should verify the signature.
  • Payload (Claims Set): A JSON object containing the claims — statements about the subject (user) and metadata about the token itself. Claims are categorized as registered (standardized names like iss, sub, exp), public (collision-resistant names from the IANA JWT Claims Registry), or private (application-specific names agreed between parties).
  • Signature: The cryptographic signature computed over the encoded header and payload (Base64URL(header) + "." + Base64URL(payload)) using the algorithm declared in the header. The signature is opaque binary data — decoding it reveals raw bytes, not meaningful JSON. A decoder displays it as a Base64URL string or hex representation for reference.

The decoder splits the token on the two dot separators, Base64URL-decodes the first two segments, and parses them as JSON. If either segment fails to decode or parse, the token is malformed. The third segment (signature) is displayed as-is since its raw bytes have no JSON structure.

Registered Claims and Token Expiration Analysis

RFC 7519 defines seven registered claim names that provide interoperable metadata about the token. A JWT decoder surfaces these claims with human-readable labels and timestamp conversions to help developers quickly assess token validity:

  • iss (Issuer): Identifies the principal that issued the JWT. Typically a URL like https://auth.example.com. Consumers validate this matches their expected identity provider.
  • sub (Subject): Identifies the principal that is the subject of the token — usually a user ID or service account identifier.
  • aud (Audience): Identifies the recipients the token is intended for. Can be a string or array. A resource server must reject tokens whose aud does not include its own identifier.
  • exp (Expiration Time): NumericDate (Unix timestamp in seconds) after which the token MUST be rejected. The decoder converts this to a human-readable date and calculates time remaining or elapsed since expiration.
  • nbf (Not Before): NumericDate before which the token MUST NOT be accepted. Used to issue tokens that activate in the future.
  • iat (Issued At): NumericDate identifying when the token was issued. Useful for determining token age and freshness.
  • jti (JWT ID): Unique identifier for the token, enabling revocation tracking and replay detection in token blacklists.

When debugging authentication failures, the most common issues are expired tokens (exp in the past), audience mismatch (aud doesn't match the API), and clock skew between the issuer and consumer. A decoder that displays timestamps in both UTC and local time alongside relative durations ("expired 3 minutes ago") makes these problems immediately visible.

Debugging Workflows: When to Decode vs Verify

JWT decoding and JWT verification serve fundamentally different purposes. Understanding when to use each prevents security mistakes while enabling efficient debugging:

  • Decode (this tool): Use during development to inspect token contents, debug claim values, check expiration timestamps, examine custom claims, and understand token structure. Decoding is a read-only operation that never validates authenticity — treat decoded claims as untrusted data in production code.
  • Verify (jwt-verifier): Use to cryptographically validate that the token was issued by a trusted party and has not been tampered with. Verification checks the signature against the issuer's key and validates temporal claims (exp, nbf). This is mandatory before trusting any claim in production.
  • Generate (jwt-generator): Use to create test tokens with specific claims for development and integration testing. Generated tokens should use test-only keys that are never deployed to production.

A typical debugging workflow: (1) copy the JWT from an API response header, browser storage, or network inspector; (2) paste into the decoder to inspect claims; (3) check exp against current time; (4) verify aud and iss match expected values; (5) examine custom claims (roles, permissions, scopes) for authorization issues. This decoder performs steps 2–5 instantly without requiring the signing key.

Security Considerations for Token Inspection

JWTs often carry sensitive information — user identifiers, email addresses, roles, organization memberships, and authorization scopes. When choosing a decoding tool, consider these security aspects:

  • Client-side processing: This tool decodes tokens entirely in the browser using JavaScript's atob() and JSON.parse(). No token data is transmitted to any server, logged, or stored beyond the current browser session. This is critical for tokens containing PII or production credentials.
  • Never trust decoded claims without verification: Any party can construct a JWT with arbitrary claims. The payload of a decoded JWT should be treated as untrusted input unless the signature has been verified against the issuer's public key. A decoded token tells you what the token claims, not what is true.
  • Token exposure: JWTs in URLs (query parameters) are logged by proxies, CDNs, and browser history. Prefer transmitting tokens in HTTP headers (Authorization: Bearer) or request bodies. When debugging, avoid pasting production tokens into online tools that may transmit data to third-party servers.
  • Algorithm confusion attacks: The decoded header reveals the signing algorithm. If a server accepts tokens with "alg": "none" or allows switching from RS256 to HS256, it may be vulnerable to signature bypass attacks. Decoding the header helps identify these misconfigurations during security audits.

Code Examples

Decoding a JWT in JavaScript (browser-safe, no dependencies)

// Decode JWT without verification — for inspection only
function decodeJwt(token) {
  const parts = token.split('.');
  if (parts.length !== 3) {
    throw new Error('Invalid JWT: expected 3 dot-separated parts');
  }

  // Base64URL → Base64 → decode → parse JSON
  function decodeSegment(segment) {
    // Replace URL-safe chars and restore padding
    const base64 = segment.replace(/-/g, '+').replace(/_/g, '/');
    const padded = base64.padEnd(
      base64.length + (4 - (base64.length % 4)) % 4, '='
    );
    const decoded = atob(padded);
    return JSON.parse(decoded);
  }

  const header = decodeSegment(parts[0]);
  const payload = decodeSegment(parts[1]);

  return { header, payload, signature: parts[2] };
}

// Example: decode an access token
const token = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.' +
  'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.' +
  'POstGetfAytaZS82wHcjoTyoqhMyxXiWdR7Nn7A29DNSl0EiXLdwJ6xC6AfgZWF1bOsS_TuYI3OG85AmiExREkrS6tDfTQ2B3WXlrr-wp5AokiRbz3_oB4OxG-W9KcEEbDRcZc0nH3L7LzYptiy1PtAylQGxHTWZXtGz4ht0bAecBgmpdgXMguEIcoqPJ1n3pIWk_dUZegpqx0Lka21H6XxUTxiy8OcaarA8zdnPUnV6AmNP3ecFawIFYdvJB_cm-GvpCSbr8G8y_Mllj8f4x9nBH8pQux89_6gUY618iYv7tuPWBFfEbLxtF2pZS6YC1aSfLQxaOoaBSTPoiHpS7s';

const { header, payload } = decodeJwt(token);
console.log('Algorithm:', header.alg);  // "RS256"
console.log('Subject:', payload.sub);    // "1234567890"
console.log('Issued:', new Date(payload.iat * 1000));

Output:

Algorithm: RS256
Subject: 1234567890
Issued: 2018-01-18T01:30:22.000Z

Checking token expiration with decoded claims

// Check if a decoded JWT is expired (with optional clock skew tolerance)
function isTokenExpired(payload, clockSkewSeconds = 30) {
  if (!payload.exp) return false; // No expiration claim
  const nowSeconds = Math.floor(Date.now() / 1000);
  return nowSeconds > (payload.exp + clockSkewSeconds);
}

// Calculate time until expiration
function tokenExpiresIn(payload) {
  if (!payload.exp) return 'No expiration set';
  const nowSeconds = Math.floor(Date.now() / 1000);
  const diff = payload.exp - nowSeconds;
  if (diff <= 0) return `Expired ${Math.abs(diff)} seconds ago`;
  if (diff < 60) return `Expires in ${diff} seconds`;
  if (diff < 3600) return `Expires in ${Math.floor(diff / 60)} minutes`;
  return `Expires in ${Math.floor(diff / 3600)} hours`;
}

Standards & Specifications

  • RFC 7519 — JSON Web Token (JWT) specification — defines token structure, registered claims, and processing rules
  • RFC 7515 — JSON Web Signature (JWS) — specifies how JWT signatures are computed and serialized in compact form
  • RFC 4648 §5 — Base64URL encoding alphabet used for all three JWT segments (URL-safe without padding)

Questions Fréquentes

Puis-je décoder un JWT sans la clé ?

Oui ! Le header et payload sont seulement encodés en Base64URL, pas chiffrés. Vous pouvez les décoder sans clé.

Est-il sûr de décoder des JWT ici ?

Oui. Tout le décodage se fait dans votre navigateur. Vos tokens ne quittent jamais votre appareil.

Quelles infos contient le payload ?

Le payload contient les claims : données utilisateur (sub, email), métadonnées (exp, iss, aud) et claims personnalisés.

Le décodage vérifie-t-il l'authenticité ?

Non. Le décodage révèle le contenu. La vérification nécessite la clé secrète ou publique.