How Base64URL Appears in JWTs

A JWT looks like random text — three groups of characters separated by dots. Each group is Base64URL-encoded. Once you understand which part contains what, decoding a JWT becomes a useful debugging technique rather than an opaque operation.

JWT structure

A JWT has three parts separated by dots: header, payload, and signature. Each is independently Base64URL-encoded:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiJ1c2VyXzEyMyIsImV4cCI6MTc0MzAwMDAwMH0
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Decode the first part: {"alg":"HS256","typ":"JWT"} — the algorithm and token type.

Decode the second part: {"sub":"user_123","exp":1743000000} — the claims: user ID and expiry timestamp.

The third part is the cryptographic signature — not human-readable JSON, just the signature bytes encoded as Base64URL.

Why Base64URL, not standard Base64

Standard Base64 uses + and / as the 62nd and 63rd characters, and pads with =. These have special meaning in URLs: + means a space, / is a path separator, = separates query string keys from values.

Base64URL replaces + with - and / with _, and omits the = padding. The result is safe to embed directly in a URL or HTTP header without percent-encoding — which is exactly what JWTs need, since they travel in Authorization headers and sometimes in URL query parameters.

Decoding manually

In a browser console:

// Decode a JWT payload
const token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyXzEyMyIsImV4cCI6MTc0MzAwMDAwMH0.abc";
const [header, payload] = token.split('.');

// Base64URL to Base64: replace - with + and _ with /
const decoded = JSON.parse(atob(payload.replace(/-/g, '+').replace(/_/g, '/')));
console.log(decoded);
// {sub: "user_123", exp: 1743000000}

What to check in a JWT payload

When debugging authentication, the payload is the most useful section. Key claims:

  • sub — subject, usually a user ID
  • exp — expiry as a Unix timestamp. Convert with new Date(exp * 1000) in JavaScript
  • iat — issued at time
  • aud — intended audience (which service should accept this token)
  • iss — issuer
The payload is not encrypted. Anyone who has the JWT can decode and read the payload — no key required. Don't include sensitive information (passwords, credit card numbers) in JWT payloads unless the token is also encrypted with JWE. The signature prevents tampering, not reading.