Understanding JWTs for API Authentication: A Practical Guide

A developer's guide to JSON Web Tokens (JWTs). Learn what they are, how they are structured, why they are the standard for securing modern REST APIs, and how they compare to traditional sessions.

In the world of modern web applications, a common problem is how to securely handle user authentication. How does a server know that a client is who they say they are, request after request? The most common solution is the JSON Web Token, or JWT (pronounced "jot").

The Old Way: Stateful Server-Side Sessions

Traditionally, a server would create a session for a user after they logged in. The server would store a session ID and send it to the client as a cookie. On each subsequent request, the client would send the cookie, and the server would look up the session ID in its database to identify the user.

This works, but it's stateful. The server has to maintain the state of every user's session, which can be difficult to scale, especially in a microservices architecture where multiple services might need to know about the user.

The JWT Way: Stateless Authentication

JWTs provide a way to do stateless authentication. Instead of storing session information on the server, the server generates a token (the JWT) when a user logs in and sends it to the client. The client then stores this token (e.g., in local storage or memory) and sends it with every subsequent request, usually in the Authorization header.

Authorization: Bearer <your_jwt_here>

The server can then validate this token on each request to identify the user, without having to look up anything in a database. This is stateless, and it's much more scalable.

The Structure of a JWT

A JWT is just a long string, but it's not random. It's composed of three parts, separated by dots (.):

xxxxx.yyyyy.zzzzz

  1. Header: Contains metadata about the token, like the type of token (JWT) and the signing algorithm being used (e.g., HS256).
  2. Payload: Contains the claims. Claims are statements about an entity (typically, the user) and additional data.
  3. Signature: This is the part that ensures the token is authentic and has not been tampered with.

Let's look at each part in detail.

1. The Header

The header is a simple JSON object that is Base64Url encoded. It typically consists of two parts:

  • alg: The signing algorithm being used (e.g., HS256 for HMAC with SHA-256).
  • typ: The type of the token, which is always JWT.
{
  "alg": "HS256",
  "typ": "JWT"
}

2. The Payload

The payload is another Base64Url encoded JSON object that contains the claims. Claims are the heart of the JWT. There are a few standard, registered claims:

  • sub (Subject): The identifier of the user (e.g., a user ID).
  • iss (Issuer): Who issued the token.
  • exp (Expiration Time): The timestamp after which the token is no longer valid. This is a crucial security feature.
  • iat (Issued At): When the token was issued.

You can also add your own public or private claims to include any information you need, like a user's roles or permissions.

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022,
  "exp": 1516242622
}

Important: The header and payload are just Base64Url encoded, not encrypted. Anyone can decode them and read their contents. Therefore, you should never put sensitive information in the payload of a JWT.

3. The Signature

This is the most critical part for security. The signature is created by taking the encoded header, the encoded payload, a secret key (that only the server knows), and signing them with the algorithm specified in the header.

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload), 
  your-256-bit-secret
)

When your API receives a JWT from a client, it performs the same signature calculation using the secret key it has stored. If the signature it generates matches the signature on the token, it proves two things:

  1. Authenticity: The token was issued by a trusted source (because only the trusted source has the secret key).
  2. Integrity: The header and payload have not been changed since the token was signed.

If the signatures don't match, the token is rejected.

The Authentication Flow

  1. A user logs in to your application with their credentials (e.g., username and password).
  2. The server validates the credentials. If they are correct, the server generates a JWT containing the user's ID and an expiration time, and signs it with its secret key.
  3. The server sends this JWT back to the client.
  4. The client stores the JWT (typically in memory or local storage).
  5. For every subsequent request to a protected API endpoint, the client includes the JWT in the Authorization header, usually with the Bearer scheme: Authorization: Bearer <token>.
  6. The API receives the request, extracts the token, and validates the signature. If the signature is valid and the token has not expired, the API trusts the claims in the payload and processes the request.

Conclusion

JWTs are a powerful and elegant solution for securing modern, stateless APIs. By understanding their three-part structure—the header, the payload, and the all-important signature—you can confidently build and consume APIs that are both secure and scalable.

Geek Cafe LogoGeek Cafe

Your trusted partner for cloud architecture, development, and technical solutions. Let's build something amazing together.

Quick Links

© 2025 Geek Cafe LLC. All rights reserved.

Research Triangle Park, North Carolina

Version: 8.8.4