When you log in to a website and stay logged in as you click around, something in the background is remembering who you are. The web’s underlying protocol, HTTP, is stateless: each request arrives with no built-in memory of the previous one. Backend developers solve this problem in two main ways, server-side sessions and tokens such as JSON Web Tokens (JWT). This article explains both in plain language and helps you choose between them.
The problem: HTTP forgets everything
Imagine a waiter who forgets every customer the moment they walk away. Every time you want something, you would have to prove who you are again. A web server behaves similarly by default. To avoid asking for a password on every click, the server gives the client something to present in later requests, a kind of proof that the login already happened. That proof can be a session identifier or a signed token.
How server-side sessions work
With sessions, the server keeps the memory. After you log in successfully, the server creates a record containing information about you, such as your user ID, and stores it in memory, a database or a cache. It then sends the browser a random, hard-to-guess session ID, usually in a cookie. On each following request, the browser sends the cookie back, and the server looks up the matching record to know who you are.
- The browser holds only an opaque identifier, not your data.
- The server holds the real information and stays in control.
- Logging a user out simply means deleting the session record.
How JWT works
A JSON Web Token flips the model. Instead of storing the user’s state on the server, the server issues a token that contains the claims itself, for example the user ID and an expiration time. The token is digitally signed, so the server can verify that nobody tampered with it. The client stores the token and sends it with each request, commonly in an Authorization header. The server checks the signature and, if it is valid and not expired, trusts the claims without looking anything up.
A JWT has three parts separated by dots: a header describing the signing algorithm, a payload with the claims, and a signature. An important detail is that the payload is encoded, not encrypted. Anyone who gets the token can read its contents, so you should never put secrets such as passwords inside it.
Strengths of sessions
Sessions are simple and well understood. Because the server owns the state, it can end a session instantly: if an account is compromised or a user logs out, deleting the record immediately invalidates access. Session data can also change on the server without the client needing a new credential. Frameworks have mature session support built in, which lowers the chance of implementation mistakes.
The cost is that the server must store and look up session data on every request. In applications running on many servers, sessions require a shared store, such as a database or an in-memory cache, so that any server can recognize the user.
Strengths of JWT
JWTs are convenient when many separate services need to verify identity without sharing a central session store. Since the token carries its own proof, any service that knows how to check the signature can authenticate the request. That is why JWTs are popular in APIs, mobile apps and microservice architectures, and in scenarios where one system issues the identity and others consume it.
The main weakness is revocation. A token that has already been issued stays valid until it expires, even if the user logs out or the account is disabled, unless you add extra machinery such as a deny list or very short lifetimes. Teams often combine short-lived access tokens with longer-lived refresh tokens to balance convenience and safety.
Side-by-side comparison
| Aspect | Server-side sessions | JWT |
|---|---|---|
| Where state lives | On the server | Inside the token on the client |
| What the client sends | An opaque session ID | A signed token with claims |
| Revoking access | Immediate, delete the record | Harder, needs expiry or deny lists |
| Server lookups | Needed on each request | Signature check only |
| Typical fit | Traditional web apps | APIs, mobile apps, distributed services |
Where to store the credential safely
Whichever approach you choose, how the browser stores the credential matters. Cookies marked HttpOnly cannot be read by JavaScript, which reduces the damage of cross-site scripting attacks. The Secure flag ensures the cookie is sent only over HTTPS, and the SameSite attribute helps limit cross-site request forgery. Storing tokens in places that scripts can read, such as local storage, is simple but exposes them if the page has a script injection flaw. Always serve login traffic over HTTPS and apply sensible expiration times.
How to choose
- If you are building a classic website with server-rendered pages, sessions are usually the simplest and safest default.
- If several independent services or clients must verify identity, JWTs can reduce coupling.
- If you need instant logout and fine control, lean toward sessions or add revocation support to tokens.
- Prefer well-tested libraries and frameworks rather than writing your own cryptography or token handling.
A common misconception
It is common to hear that JWTs are “more modern” and therefore better. In reality, neither approach is universally superior. Many applications adopt tokens when a simple session would have worked perfectly well, inheriting extra complexity for no benefit. Choose based on your architecture and requirements, not trends.
Conclusion
Sessions and JWTs both answer the same question: how does the server know who is making this request? Sessions keep the memory on the server, while JWTs carry signed information with the client. Understanding the trade-offs puts you in a better position to design secure login systems. If you want to go deeper into backend development, explore the related programming and web development courses available on Cursa.



























