What Is a JWT Token? Structure, Claims, and Security Explained

JWTs are three Base64URL-encoded parts separated by dots. We dissect every field — header, payload, signature — explain registered claims like iss/exp/sub, and show what ToollyX's JWT Decoder reveals.

A JWT looks like gibberish — three base64url-encoded strings separated by dots. But every part has a precise meaning, and misunderstanding JWTs leads to serious security vulnerabilities. This article dissects every component, explains the registered claims the spec defines, and shows what ToollyX's JWT Decoder reveals when you paste one in.

The Three Parts of a JWT

A JWT is exactly three Base64url-encoded JSON objects, separated by dots:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNzA5MDAwMDAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
{ "alg": "HS256", "typ": "JWT" }
Payload
eyJzdWIiOiIxMjM0NTY3ODkw...
{ "sub": "1234567890", "name": "Alice", "iat": 1709000000 }
Signature
SflKxwRJSMeKKF2QT4fw...
HMAC-SHA256(header.payload, secret)

Part 1: The Header

The header declares how the token is signed. Two fields are standard:

  • alg — the signing algorithm. Common values: HS256 (HMAC-SHA256, symmetric), RS256 (RSA-SHA256, asymmetric), ES256 (ECDSA, elliptic curve).
  • typ — token type. Always "JWT".

Critical security note: Never accept "alg": "none" — this means no signature, and was exploited in a famous 2015 JWT attack.

Part 2: The Payload (Claims)

Claims are statements about the subject. The JWT spec defines seven registered claims:

ClaimFull NameTypeNotes
issIssuerStringWho created the token (e.g., "auth.yourdomain.com")
subSubjectStringWho the token is about (usually user ID)
audAudienceString/ArrayIntended recipient(s) — validate this server-side
expExpiration TimeNumericDateUnix timestamp after which token must be rejected
nbfNot BeforeNumericDateUnix timestamp before which token must not be accepted
iatIssued AtNumericDateWhen the token was issued
jtiJWT IDStringUnique identifier — enables token revocation lists

Everything else in the payload is a private claim — application-specific data like role, email, plan.

Part 3: The Signature

The signature is computed as:

signature = HMAC-SHA256(
  base64url(header) + "." + base64url(payload),
  secret
)

For RS256, the private key signs and the public key verifies — allowing any service to validate a token without knowing the secret. For HS256, the same secret signs and verifies — simpler but requires sharing the secret between all verifiers.

JWT Is Not Encrypted — Anyone Can Read It

Base64url is encoding, not encryption. Anyone who intercepts a JWT can decode the header and payload instantly. Never put sensitive data in JWT claims — no passwords, no credit card numbers, no SSNs. The signature only proves the token wasn't tampered with; it doesn't hide the payload.

If you need confidentiality in the payload, use JWE (JSON Web Encryption) — a different standard that encrypts the payload. Standard JWTs are transparent.

What ToollyX JWT Decoder Shows

Paste a JWT into the JWT Decoder and it:

  • Splits the token into its three parts and shows the raw Base64url for each
  • Pretty-prints the header and payload JSON with syntax highlighting (keys in purple, string values in green, numbers in blue, booleans in orange)
  • Converts exp, nbf, and iat from Unix timestamps to human-readable UTC dates
  • Shows expiry state: Valid, Expires in <5 minutes, or Expired
  • Labels all registered claims with their full names (e.g., "Expiration Time" for exp)
  • Allows copying header, payload, or signature individually

The sample JWT in the tool decodes to show Alice Johnson with admin role — useful for testing the tool before pasting your own token.

Common JWT Security Mistakes

  • Not validating exp server-side — An expired token should always be rejected, even if the signature is valid.
  • Accepting "alg": "none" — Never. Always whitelist specific algorithms.
  • Storing JWTs in localStorage — Vulnerable to XSS. Use httpOnly cookies.
  • Using a weak secret for HS256 — The secret must be long and random. Generate one with the Password Generator.
  • Not validating aud claim — A token issued for your mobile app shouldn't be accepted by your API.
🪙
Decode and inspect any JWT

Expiry status, claim labels, syntax highlighting. No data sent to server.

Open JWT Decoder →