Blog

Tips, tutorials, and insights about online tools

How to Decode a JWT Token Online for Free
2026-08-20Keynou Team

How to Decode a JWT Token Online for Free

A JSON Web Token (JWT) is a compact, URL-safe string used for authentication and information exchange. When you decode a JWT token, you split it into its three components — header, payload, and signature — and decode each part to inspect the claims, algorithm, and expiration. This is essential for debugging authentication flows, verifying token expiration, and checking which signing algorithm a service uses. A browser-based decoder does this instantly without writing a script or sending your token to a server. This guide covers JWT structure, the decoding process, common claims, algorithm types, and the critical security distinction between decoding and verifying.

JWT Structure: Header.Payload.Signature

A JWT consists of three Base64URL-encoded parts separated by dots:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiZXhwIjoxNzMyNzU4NDAwfQ.sN3aZqKJ8wQyVbR5xT9mF2pL6hY0jN4kD7sW1cE3bA

Each part serves a specific purpose:

<svg viewBox="0 0 800 260" xmlns="http://www.w3.org/2000/svg" style="width:100%;max-width:800px;margin:24px auto;display:block">
  <rect x="0" y="0" width="800" height="260" fill="#f8fafc" rx="12"/>
  <text x="400" y="35" fill="#1e293b" font-size="17" font-family="sans-serif" text-anchor="middle" font-weight="bold">JWT Token Structure</text>
  <rect x="30" y="60" width="240" height="120" fill="#3b82f6" rx="8"/>
  <text x="150" y="90" fill="white" font-size="14" font-family="sans-serif" text-anchor="middle" font-weight="bold">Header</text>
  <text x="150" y="115" fill="#dbeafe" font-size="11" font-family="sans-serif" text-anchor="middle">Algorithm &amp; token type</text>
  <text x="150" y="140" fill="#dbeafe" font-size="10" font-family="monospace" text-anchor="middle">{"alg":"HS256","typ":"JWT"}</text>
  <text x="150" y="165" fill="#dbeafe" font-size="11" font-family="sans-serif" text-anchor="middle">Base64URL encoded</text>
  <text x="280" y="120" fill="#94a3b8" font-size="24" font-family="sans-serif" text-anchor="middle" font-weight="bold">.</text>
  <rect x="295" y="60" width="240" height="120" fill="#8b5cf6" rx="8"/>
  <text x="415" y="90" fill="white" font-size="14" font-family="sans-serif" text-anchor="middle" font-weight="bold">Payload</text>
  <text x="415" y="115" fill="#ede9fe" font-size="11" font-family="sans-serif" text-anchor="middle">Claims (user data)</text>
  <text x="415" y="140" fill="#ede9fe" font-size="10" font-family="monospace" text-anchor="middle">{"sub":"123","name":"Alice"}</text>
  <text x="415" y="165" fill="#ede9fe" font-size="11" font-family="sans-serif" text-anchor="middle">Base64URL encoded</text>
  <text x="545" y="120" fill="#94a3b8" font-size="24" font-family="sans-serif" text-anchor="middle" font-weight="bold">.</text>
  <rect x="560" y="60" width="210" height="120" fill="#f59e0b" rx="8"/>
  <text x="665" y="90" fill="white" font-size="14" font-family="sans-serif" text-anchor="middle" font-weight="bold">Signature</text>
  <text x="665" y="115" fill="#fef3c7" font-size="11" font-family="sans-serif" text-anchor="middle">HMAC or RSA signature</text>
  <text x="665" y="140" fill="#fef3c7" font-size="10" font-family="monospace" text-anchor="middle">HMAC-SHA256(...)</text>
  <text x="665" y="165" fill="#fef3c7" font-size="11" font-family="sans-serif" text-anchor="middle">Not decoded — verified</text>
  <text x="150" y="220" fill="#64748b" font-size="11" font-family="sans-serif" text-anchor="middle">Decoded to view</text>
  <text x="415" y="220" fill="#64748b" font-size="11" font-family="sans-serif" text-anchor="middle">Decoded to view</text>
  <text x="665" y="220" fill="#64748b" font-size="11" font-family="sans-serif" text-anchor="middle">Verified with secret/key</text>
</svg>

The JWT decoder splits the token at the dots, Base64URL-decodes the header and payload, and displays them as formatted JSON. The signature is not decoded — it's a cryptographic value that you verify, not read.

How to Decode a JWT Token

Decoding a JWT is straightforward because the header and payload are Base64URL-encoded, not encrypted. Anyone with the token can read them.

Step 1: Split the Token

Split the JWT at the dot separators to get three strings:

const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiZXhwIjoxNzMyNzU4NDAwfQ.signature";
const [headerB64, payloadB64, signatureB64] = token.split(".");

Step 2: Base64URL-Decode Each Part

JWT uses Base64URL encoding, which replaces + with - and / with _, and omits padding. You need to reverse this before decoding:

function base64UrlDecode(str) {
  let base64 = str.replace(/-/g, '+').replace(/_/g, '/');
  while (base64.length % 4) base64 += '=';
  return atob(base64);
}

const header = JSON.parse(base64UrlDecode(headerB64));
const payload = JSON.parse(base64UrlDecode(payloadB64));

console.log(header);   // { alg: "HS256", typ: "JWT" }
console.log(payload);  // { sub: "1234567890", name: "Alice", exp: 1732758400 }

You can also use the Base64 converter to decode individual parts manually if you're inspecting a token outside of code.

Common JWT Claims

The payload contains claims — statements about the token and the user. Standard claims are defined in RFC 7519:

Claim Name Description
iss Issuer Who issued the token
sub Subject Who the token is about (usually user ID)
aud Audience Intended recipient of the token
exp Expiration When the token expires (Unix timestamp)
nbf Not Before When the token becomes valid
iat Issued At When the token was created
jti JWT ID Unique identifier for the token

Custom claims are anything the issuer adds — name, email, role, permissions. These vary by application.

Checking Expiration

The exp claim is a Unix timestamp. A good decoder converts it to a human-readable date and tells you whether the token is currently valid or expired. This is the most common debugging task — "why is my API returning 401?" is often an expired token.

Algorithm Types

The alg field in the header specifies how the signature was generated:

Algorithm Type Key Use Case
HS256 HMAC + SHA-256 Shared secret Simple setups, single server
RS256 RSA + SHA-256 Public/private key pair Distributed systems, microservices
ES256 ECDSA + SHA-256 Elliptic curve key pair Performance-sensitive systems

HMAC algorithms use a shared secret. RSA and ECDSA use asymmetric keys — the issuer signs with a private key, verifiers check with a public key. Asymmetric algorithms are preferred when multiple services need to verify tokens without sharing the signing key.

Decoding vs. Verifying: A Critical Distinction

Decoding a JWT only reads the contents — it does not verify authenticity. Anyone can create a JWT with any claims they want. To confirm a token was issued by the expected party and hasn't been modified, you must verify the signature using the secret (for HMAC) or public key (for RSA/ECDSA).

The JWT decoder shows the decoded contents and lets you verify the signature if you provide the secret or public key. For a deeper dive into how JWT authentication works end-to-end, see our jwt decoder online guide.

Security Notes

  • JWTs are not encrypted — the header and payload are readable by anyone with the token. Never put passwords, API keys, or sensitive data in claims.
  • Always verify signatures in production — decoding is for debugging; your backend must verify signatures before trusting any claim.
  • Watch for alg: none — some older implementations accepted tokens with no signature. Modern libraries reject this, but it's worth checking.

Published: August 20, 2026
Category: Data Tools
Reading Time: 5 minutes

Verified DR - Verified Domain Rating for keynou.com
FlowDrive