Session Management
HTTP forgets who you are after every request. You have to keep reminding it. Here is how.
The problem
HTTP is stateless. Every request stands alone. The server has no memory of the previous request. But your app needs to know who is logged in. So how do you do that?
The basic answer. The client carries some kind of ID with every request. The server reads the ID and looks up "who is this person?"
There are two main approaches.
Server-side sessions. The server keeps a table of who is logged in. The client only carries a key into that table.
Tokens. The server gives the client a small, signed piece of data. The data itself says who the user is. The server just verifies the signature.
Both are used in real systems. The right choice depends on what you are building.
Approach 1. Server-side sessions
When you log in, the server generates a random ID, like "abc123." It saves a row in a session table that says "session abc123 belongs to user 42." Then it sets a cookie in the response, like Set-Cookie: session=abc123.
From then on, your browser automatically sends that cookie with every request. The server reads the cookie, looks up "abc123" in its session table, and figures out you are user 42.
Where does the session table live? Not in each web server's memory. That would tie you to one specific server. It lives in a shared store, like Redis, Memcached, or a database. Every web server can look up any session ID.
This is how traditional web apps worked for a long time. It is still common.
Approach 2. Tokens (JWT)
The other approach is to skip the session table entirely. When you log in, the server gives you a signed token. The most common kind is called a JWT, which stands for JSON Web Token.
The token itself contains your user info, like { "user_id": 42, "exp": 1735689600 }, plus a cryptographic signature. The signature is generated using a secret key that only the server knows.
Your browser stores the token (in a cookie or in browser storage) and sends it on every request. The server verifies the signature against its secret key. If the signature is valid, the server trusts what is in the token. No table lookup needed.
The good part. No shared session store. Every server can verify a token on its own. Scaling horizontally is trivial. Tokens can also be passed between different services without each service needing to look up the user.
The bad part. Tokens are hard to invalidate. If a user logs out, or you want to ban them, their existing tokens still work until they expire. The usual workaround is short token expirations combined with a refresh token system. Or you keep a list of revoked tokens (which puts you back into needing a shared store).
This is the dominant pattern in modern APIs, especially when mobile apps and third-party clients are involved.
Which one to pick
Use server-side sessions when:
You need the ability to invalidate sessions immediately. An admin needs to be able to force-log-out a user. The data you want to keep per session is large. You do not want every request carrying it all. You are building a traditional web app and the user is mostly on one device.
Use tokens when:
You are building APIs used by mobile apps or third-party clients. You want to scale across many independent services without coordinating session lookups. You are running stateless serverless functions where there is no convenient place to keep a session.
A lot of real systems mix both. They use short-lived tokens for API auth, and they store refresh tokens server-side so they can be revoked when needed.