DevBolt
·8 min read

Understanding JWTs: A Developer's Guide to JSON Web Tokens

AuthenticationSecurityWeb Development

JSON Web Tokens (JWTs) are everywhere in modern web development. If you've built an API, used OAuth, or integrated a third-party service, you've almost certainly encountered one. This guide explains what they are, how they work, and the mistakes that trip up most developers.

What Is a JWT?

A JWT is a compact, URL-safe string that carries a set of claims between two parties. It's commonly used for authentication — after a user logs in, the server issues a JWT that the client sends with subsequent requests to prove identity.

Unlike session-based auth where the server stores state, JWTs are stateless. The token itself contains all the information the server needs to validate the request.

JWT Structure: Three Parts

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

JWT format
header.payload.signature

1. Header

The header declares the token type and signing algorithm:

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

Common algorithms include HS256 (HMAC + SHA-256), RS256 (RSA + SHA-256), and ES256 (ECDSA + SHA-256). The choice of algorithm determines how the signature is created and verified.

2. Payload

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

Decoded payload
{
  "sub": "1234567890",
  "name": "Jane Developer",
  "email": "jane@example.com",
  "role": "admin",
  "iat": 1710700800,
  "exp": 1710787200
}

3. Signature

The signature is created by signing the encoded header and payload with a secret key. For HS256:

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

The signature ensures the token hasn't been tampered with. If anyone changes the payload, the signature won't match and the server will reject the token.

Standard Claims

The JWT spec defines several registered claims. None are required, but they're widely used:

ClaimNameDescription
issIssuerWho created the token
subSubjectWho the token is about (usually a user ID)
audAudienceWho the token is intended for
expExpirationUnix timestamp when the token expires
iatIssued AtUnix timestamp when the token was created
nbfNot BeforeToken is invalid before this time

How JWT Authentication Works

  1. 1The user sends credentials (email + password) to your login endpoint.
  2. 2The server verifies the credentials, creates a JWT with the user's claims, and signs it with a secret key.
  3. 3The client stores the JWT (commonly in memory or an httpOnly cookie) and includes it in the Authorization header of subsequent requests.
  4. 4The server verifies the signature and checks expiration on each request — no database lookup needed.
Authorization header
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRGV2ZWxvcGVyIiwiaWF0IjoxNzEwNzAwODAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Common Mistakes and Security Pitfalls

Storing JWTs in localStorage

localStorage is accessible to any JavaScript running on the page, making it vulnerable to XSS attacks. Prefer httpOnly cookies — they're not accessible via JavaScript and are sent automatically with requests.

Not Validating the Algorithm

The classic alg: "none" attack works when servers blindly trust the algorithm specified in the header. Always validate that the algorithm matches what your server expects. Most modern JWT libraries handle this, but double-check your configuration.

Setting Tokens That Never Expire

A stolen token without an expiration is a permanent key. Always set a reasonable exp claim. For access tokens, 15-60 minutes is common. Use refresh tokens for longer sessions.

Putting Sensitive Data in the Payload

The payload is encoded, not encrypted. Anyone can decode it with a Base64 decoder. Never include passwords, API keys, or other secrets in the payload. Use our JWT Decoder to see how easy it is to read the payload of any JWT.

When to Use JWTs (and When Not To)

Good use cases:

  • Stateless API authentication across microservices
  • Single sign-on (SSO) between applications
  • Short-lived authorization tokens (OAuth 2.0 access tokens)

Consider alternatives when:

  • You need to revoke tokens immediately (JWTs are valid until they expire)
  • You're building a simple server-rendered app (session cookies are simpler)
  • Token payload would be very large (JWTs are sent with every request)

Try It Yourself

Paste any JWT into our JWT Decoder to instantly see its header, payload, and expiration status — all decoded locally in your browser. You can also use the Base64 Decoder to manually decode individual JWT parts, or the Hash Generator to explore the SHA-256 algorithm used in JWT signatures.