DevKnightUtils logo
JWT Decoded: What's Really Inside Your Token
securitytutorialjavascript

JWT Decoded: What's Really Inside Your Token

Understand the three parts of a JWT — header, payload, and signature — and learn when to use tokens vs sessions, common mistakes, and security best practices.


You've seen them everywhere: long strings of random-looking characters separated by two dots, passed in Authorization headers on every API request. But do you actually know what's inside a JWT? Most developers use them without fully understanding what they contain — and that's where security bugs are born.

In this post we'll open up a JWT, explain each part, and cover the common mistakes that could expose your users' data.

What Is a JWT?

A JSON Web Token (JWT) is an open standard (RFC 7519) for securely transmitting information between parties as a compact, URL-safe string. It looks like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

That string is three Base64Url-encoded sections separated by dots: header, payload, and signature.

Breaking It Down

Header

The header declares the token type and the signing algorithm:

{
  "alg": "HS256",
  "typ": "JWT"
}

Common algorithms: HS256 (HMAC-SHA256, shared secret) and RS256 (RSA, public/private key pair). For APIs shared between services, prefer RS256 — the private key signs, any service with the public key can verify.

Payload

The payload contains claims — statements about the user and other metadata:

{
  "sub": "1234567890",
  "name": "Jane Doe",
  "email": "[email protected]",
  "role": "admin",
  "iat": 1516239022,
  "exp": 1516242622
}

Key reserved claims:

  • sub — Subject (usually the user ID)
  • iat — Issued At (Unix timestamp)
  • exp — Expiration time (Unix timestamp) — always include this
  • iss — Issuer (your server's URL)
  • aud — Audience (intended recipient)

⚠️ Aviso: The payload is only Base64Url encoded, not encrypted. Anyone with the token can decode and read the claims. Never store passwords, credit card numbers, or other sensitive data in a JWT payload.

Signature

The signature is what makes the token trustworthy:

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

The server verifies the signature on every request. If someone tampers with the payload, the signature won't match and the token will be rejected. This is the core security property of JWTs.

JWT vs Sessions: Which Should You Use?

JWT Sessions
State Stateless (no DB lookup) Stateful (requires session store)
Revocation Hard (token lives until exp) Easy (delete from store)
Scalability Great for microservices Needs shared session store
Size Larger (sent every request) Small (just a session ID)

Use JWTs when you have multiple services that need to verify identity without sharing a database. Use sessions when you need instant revocation (e.g. "log out all devices").

Common Mistakes

1. Storing JWTs in localStorage localStorage is accessible via JavaScript and vulnerable to XSS attacks. Store JWTs in httpOnly cookies instead.

2. Not validating exp Always check the expiration claim server-side. Don't assume your JWT library does this automatically — read the docs.

3. Using alg: none Some early JWT libraries accepted tokens with "alg": "none" — meaning no signature verification. Never allow this algorithm in your server.

4. Huge payloads JWTs are sent on every request. Keep payloads small. Store large user data in the database and fetch it on demand.

Resources

Wrap Up

JWTs are powerful but misunderstood. The key takeaways: always include exp, never store sensitive data in the payload, use httpOnly cookies for storage, and verify the signature server-side every time.

Ready to inspect a JWT from your own app? Paste it into our free JWT Decoder to see the header and payload decoded instantly — no server, no data sent anywhere.

We use Google AdSense and Google Analytics cookies to show relevant ads and collect usage statistics. You can accept or reject non-essential cookies. Read our Privacy Policy for more information.