Buy Me a Coffee

How Web Authentication (Cookies, Sessions, JWT) Actually Works

Conceptual illustration of cookies, sessions, and JWT authentication flow

Authentication on the web often feels confusing not because it is complicated, but because its core ideas are rarely explained in a clean order.

This post builds that order.

We will start from the nature of the web itself, explain cookies and server-side sessions as a single coherent model, then expand outward to JWT and why it fits modern distributed systems.

The goal is not to overwhelm you, but to give you a mental model you can reuse.

1. Why the Web Needs Help Remembering Users

The web is built on HTTP, which is stateless.

That means:

  • Each request is independent
  • The server does not remember previous requests by default
  • Every request looks like a brand-new visitor

Yet real applications need to remember:

  • Who the user is
  • Whether they are authenticated
  • Temporary state like preferences

So the first problem to solve is simple:

How can the server recognize the same user across multiple requests?

The answer begins with cookies.

2. Cookies and Server-Side Sessions: One Model, Two Roles

Cookies: identification on the client

A cookie is a small piece of data stored in the browser.

Important properties:

  • Lives on the client (browser)
  • Automatically sent with every request to the same domain
  • Small and simple
  • Treated as untrusted input by the server

Conceptually, a cookie often looks like:

session_id=abc123

A cookie does not contain meaning by itself.
It only identifies something.

Server-side sessions: state on the server

A server-side session is data stored by the backend.

It typically contains:

  • User identity
  • Authentication state
  • Temporary per-user data

Example (server-side):

session_id: abc123
user_id: 42
role: admin

The browser never sees this data directly.

The core relationship

This is the most important idea in this post:

Cookies identify a user. e.g. Store session_id=abc123, each session_id maps to a session on the server.
Sessions store the user’s state. Each session_id maps to a real user’s data, e.g. user_id=42, role=admin.

They are not alternatives.
They are designed to work together.

Let’s look at the full workflow.

flowchart LR A[Browser] -->|Request| B[Server] B -->|Create or load session| C[(Session Store)] B -->|Set-Cookie session_id| A A -->|Next request with cookie| B

What happens conceptually

  1. The browser sends a request
  2. The server creates or loads a session
  3. The server associates the session with a session ID
  4. The server sends the session ID back as a cookie
  5. The browser automatically includes the cookie in future requests
  6. The server uses the session to determine user state

Important:

  • The browser does not know authentication logic
  • The server makes all decisions on each request

This model fits naturally with server-rendered applications.

4. Cookies Are Transport, Not Architecture

A common misunderstanding is assuming that using cookies automatically means using server-side sessions.

That is not true.

Cookies are just a way to send data from client to server.

Two common patterns:

  • Cookie contains a session ID
  • Server loads session data from storage
  • Identity lives on the server
  • Cookie contains a signed token
  • Server verifies the token directly
  • No session lookup is required

So the correct mental model is:

Cookies are transport. e.g. Cookies can carry session IDs or JWTs.
Sessions and tokens are architectural choices. Session implies server-side state; JWT implies stateless verification.

5. Server-Side Sessions vs JWT: Two Different Tradeoffs

Server-side sessions

Characteristics:

  • Stateful
  • Server retains full control
  • Easy to invalidate
  • Sensitive data stays on the server

Best suited for:

  • Server-side rendered apps
  • Admin interfaces
  • Systems prioritizing control and simplicity

JWT (JSON Web Token)

JWT takes a different approach:

The user’s identity is embedded inside the token itself.

JWT flow:

flowchart LR A[Client] -->|Authenticate| B[Auth Server] B -->|Issue JWT| A A -->|Request with JWT| C[API] C -->|Verify signature| C

JWT contains:

  • User identity
  • Claims or roles
  • Expiration time
  • Cryptographic signature

The server verifies the token but does not store session state.

Before understanding why JWT fits modern systems, we need to recognize the challenges of using server-side sessions in distributed environments.

Challenges of server-side sessions in distributed systems

In a distributed system with multiple backend services, if a user logs in, the session data is only created in one backend service. But the next request might go to a different service that does not have access to the session data. This requires all services to share a common session store (e.g., Redis), which adds complexity and potential bottlenecks. It counteracts the needs of scalability and independence among services.

How JWT solves these challenges

JWT aligns well with modern system constraints:

  • Stateless services
  • Horizontal scaling
  • Microservice architectures
  • Multiple client types (web, mobile, API)

Because no shared session store is required:

  • Services are easier to scale
  • Infrastructure coordination is reduced

More specifically:

  • Decoupling: Each service can independently verify tokens without relying on a central session store.
  • Performance: Reduces latency by eliminating session lookups.
  • Flexibility: Works well across different domains and client types.

This is why many real systems adopt a hybrid approach:

  • Server-side sessions at the web boundary
  • JWT between APIs and services

Final Mental Model

To keep everything straight, remember this:

  • Cookies are envelopes. They carry data between client and server.
  • Sessions are filing cabinets. They store user state on the server.
  • Session ID is the label on the envelope that points to the right filing cabinet. Session ID is stored in cookies so that it can be sent to the server.
  • JWTs are self-contained passports. They carry identity and claims within themselves.

Each exists for a reason.

Understanding which problem each one solves is the foundation of designing authentication systems that are clear, scalable, and predictable.


Enjoyed this article? Support my work with a coffee ☕ on Ko-fi.
Buy Me a Coffee at ko-fi.com
DigitalOcean Referral Badge
Sign up to get $200, 60-day account credit !