JWT Decoder & Inspector

Paste any JWT to instantly decode the header, payload, and signature. See expiry status, relative time remaining, and security warnings. Your tokens are never sent to any server.

How It Works

  1. 1

    Paste your JWT token into the input field — all three sections are decoded instantly

  2. 2

    Click any color-coded section (blue=header, purple=payload, red=signature) to copy the raw base64url segment

  3. 3

    Check the claims table for all payload fields with timestamps shown as both Unix and human-readable dates

When To Use This Tool

  • When debugging an authentication issue and you need to see what claims are inside a token

  • When a login or API request fails and you want to check if the token has expired

  • When onboarding to a new API that uses JWTs and you want to understand the token structure

  • When investigating a security report and need to inspect the algorithm and claims of a token

  • When writing tests that include JWTs and you need to verify the payload contents

Frequently Asked Questions

Complete Guide to JSON Web Tokens (JWTs)

JWT structure: header, payload, signature

A JWT is three base64url-encoded JSON objects separated by dots. The Header contains the token type ('JWT') and the signing algorithm ('HS256', 'RS256', etc.). The Payload contains claims — name/value pairs about the user or session. The Signature is computed by the issuer: HMAC-SHA256(base64url(header) + '.' + base64url(payload), secret). The complete token is header.payload.signature, all base64url-encoded. Dots are used as separators because they are safe in URLs and cannot appear in base64url-encoded data.

Authentication flow with JWTs

The standard flow: (1) User submits credentials to POST /login. (2) Server verifies credentials, creates a JWT payload with user ID and roles, signs it with the secret key, returns the token. (3) Client stores the token (localStorage or httpOnly cookie). (4) Client sends the token in the Authorization header: 'Bearer {token}' on subsequent requests. (5) Server validates the signature, checks expiry, reads claims — no database lookup required. (6) When the token expires, the client uses a refresh token to get a new access token. The key advantage: the server is stateless — it does not need to store sessions.

Common JWT vulnerabilities

Algorithm confusion: some libraries accept tokens with alg: none or allow the client to specify the algorithm. Fix: always specify expected algorithms explicitly. Key confusion: HS256 and RS256 use different key types. A library that accepts both may be confused into using the RS256 public key as an HMAC secret. Secret exposure: weak or hardcoded secrets can be brute-forced. Use cryptographically random secrets of at least 256 bits. Missing expiry: tokens without exp claim never expire — if stolen, they grant permanent access. Token leakage: JWTs in query strings appear in server logs and browser history — always use the Authorization header. Overly permissive CORS: if your API accepts tokens from any origin, attackers on other pages can access it.

JWT libraries and validation in code

Node.js: jsonwebtoken — jwt.sign(payload, secret), jwt.verify(token, secret). Python: PyJWT — jwt.encode(payload, key), jwt.decode(token, key, algorithms=['HS256']). Java: nimbus-jose-jwt, auth0/java-jwt. Go: golang-jwt/jwt. PHP: firebase/php-jwt. Ruby: ruby-jwt. C#: System.IdentityModel.Tokens.Jwt. All libraries follow the same pattern: specify the algorithm and key explicitly when decoding. Never use a decode-only function without signature verification in production code — decoding without verification bypasses the security entirely.

JWKS: JSON Web Key Sets for RS256

When using RS256 (asymmetric), the public key must be distributed to all services that verify tokens. JWKS (JSON Web Key Sets) is the standard for publishing public keys at a well-known URL (typically /.well-known/jwks.json). Each key has a kid (key ID) field. The JWT header includes the kid so verifiers know which key to use. This enables key rotation: add a new key to JWKS, start signing with it, remove the old key after old tokens expire. Auth providers (Auth0, Okta, Cognito, Keycloak) publish JWKS endpoints automatically. Services fetch and cache the public keys periodically.

Storing JWTs securely in the browser

Two options: localStorage and httpOnly cookies. localStorage is accessible to JavaScript on the page — vulnerable to XSS attacks where injected script steals the token. httpOnly cookies cannot be accessed by JavaScript — immune to XSS — but vulnerable to CSRF attacks (though CSRF mitigations are well-understood). For most applications, httpOnly cookies with SameSite=Strict or SameSite=Lax and CSRF tokens is the more secure option. localStorage is simpler to implement and acceptable for low-risk applications with strong Content Security Policy headers. The critical decision: what is the risk profile of a stolen token and what attacks are you defending against?

Token revocation strategies

JWTs are stateless — once issued, they are valid until expiry with no database lookup. This makes revocation hard. Strategies: (1) Short expiry — 15 minutes or less — minimizes the window a stolen token is useful. Requires refresh tokens for practical sessions. (2) Blocklist — store revoked JWT IDs (jti claim) in Redis with TTL matching the token's remaining lifetime. Adds a cache lookup to every request but allows immediate revocation. (3) Rotation — issue a new token on every request and invalidate the previous one. Requires state but provides single-use semantics. (4) User version — store a version number per user; include it in the JWT; revoke all tokens by incrementing the version. Each strategy trades statefulness against revocation immediacy.

Was this tool helpful?

Related Tools

This free JWT decoder and inspector decodes JSON Web Tokens client-side — header, payload, signature, expiry status, and security warnings. Supports HS256, RS256, and all standard JWT algorithms. Your tokens never leave your browser.

This tool runs entirely in your browser. Your JWT tokens are never sent to any server.