Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 36

Session vs. Token Authentication

Recommended resources

Hello! Welcome back to our backend engineering course.

In our last lesson, we took a deep dive into password security, understanding how Django uses salted, slow hashing to protect user credentials. We now know how to verify a user's identity when they log in. But what happens next?

The HTTP protocol that powers the web is inherently stateless. This means each request from a client to a server is treated as an independent transaction, with no memory of previous requests. So, after a user logs in successfully, how does the server know it's the same user making subsequent requests for their profile or other protected data?

This lesson tackles that fundamental problem. We will compare the two dominant strategies for maintaining a user's authenticated state across multiple requests, directly addressing the learning outcome: Compare session-based and token-based authentication strategies. Understanding this trade-off is crucial for designing scalable and secure backend systems.

1. Strategy 1: Session-Based Authentication (The Stateful Server)

The first approach is the traditional method used by Django and many web frameworks. In this model, the server takes on the responsibility of "remembering" the user.

Here's how it works:

  1. A user sends their credentials (e.g., username and password) to a login endpoint.
  2. The server validates these credentials.
  3. Upon success, the server creates a "session" record. This record, which contains information like the user's ID, is stored server-side (typically in a database or a fast in-memory cache like Redis).
  4. The server generates a unique, random string called a Session ID to identify this session record.
  5. The server sends this Session ID back to the client, placing it inside an HTTP cookie.
  6. For every following request to the same server, the client's browser automatically includes this cookie.
  7. The server reads the Session ID from the cookie, looks up the corresponding session record in its storage, and identifies the user.

This flow makes the server stateful because it must maintain the state of every active user session.

The following sequence diagram illustrates this entire interaction.

Session Based Authentication Flow
This diagram shows the step-by-step process of session-based authentication. The server creates and stores session data upon login, sending only a Session ID to the client via a cookie. Subsequent requests are authenticated by looking up this ID on the server.

To see this explained dynamically, let's watch a short segment from a video by ByteByteGo.

Session Vs JWT: The Differences You May Not Know!

This video provides a clear, animated explanation of the session-based authentication flow. Pay close attention to where the session data is stored and what is exchanged between the client and server.

Watch the section from 00:19 to 01:12. Focus on the role of the server's session store and the session ID cookie.

Pros and Cons of Session-Based Authentication

This approach has some clear advantages and disadvantages.

Pros:

  • Server-Side Control: Since the session data lives on the server, you have full control. You can invalidate a session instantly (e.g., forcing a user to log out) by simply deleting the session record from your database.
  • Simplicity for Traditional Web Apps: It's a well-understood pattern that integrates seamlessly with browser-based applications, as cookies are handled automatically. Django's default authentication is session-based.
  • Less Data Exposure: Only a meaningless Session ID is stored on the client. The actual user information remains on the server.

Cons:

  • Scalability Challenges: In a distributed system with multiple server instances, each server needs to be able to access the session data. This requires a centralized session store (like a shared database or Redis), which adds complexity, another point of failure, and potential latency to your architecture.
  • Stateful Overhead: The server must store session data for every active user, consuming memory and storage resources.

2. Strategy 2: Token-Based Authentication (The Stateless Server)

Token-based authentication flips the responsibility. Instead of the server remembering the user, the client is given a "token" that proves its identity. This allows the server to become stateless.

The most common form of this is JSON Web Token (JWT) authentication.

Here's the flow:

  1. A user sends their credentials to a login endpoint.
  2. The server validates these credentials.
  3. Upon success, the server generates a token. This token is not random; it's a carefully constructed JSON object containing user details (like user_id) and an expiration date. This object is then digitally signed with a secret key known only to the server.
  4. The server sends this signed token back to the client.
  5. The client stores this token (e.g., in browser local storage).
  6. For every following request to a protected endpoint, the client must manually include the token, typically in the Authorization HTTP header.
  7. The server receives the token, verifies its signature using the secret key, and if the signature is valid, it trusts the information inside the token.

Crucially, the server does not need to store the token or look it up in a database. The cryptographic signature guarantees that the token was issued by the server and has not been tampered with.

Session Vs JWT: The Differences You May Not Know!

Now let's watch the corresponding segment on JWT-based authentication from the same video. Notice the key difference: there is no session store on the server.

Watch the section from 01:43 to 02:40. Focus on how the server generates and verifies the token without storing any state.

This stateless nature is the defining feature of JWTs. A short clip from a video by BugBytes, in the context of Django, drives this point home.

Django REST Framework - JWT Authentication with djangorestframework-simplejwt

This video snippet explains why JWTs are performant and scalable by highlighting the absence of a database lookup.

Watch from 05:04 to 05:33. The key takeaway is that the server can validate the token without a database query.

Pros and Cons of Token-Based Authentication

Pros:

  • Stateless and Scalable: Since the server doesn't store session state, you can easily add more server instances without worrying about a shared session store. This is ideal for microservices and large-scale applications.
  • Decoupled and Flexible: A token issued by one service can be verified by any other service that knows the secret key. This makes it perfect for APIs consumed by different clients (web, mobile, other backend services).

Cons:

  • Token Invalidation: This is the biggest challenge. Since the token is self-contained and lives on the client, you cannot simply "delete" it from the server. If a token is stolen, it remains valid until it expires.
  • Token Size: The token can become large if you store a lot of data (claims) in it, increasing the size of every request.
  • Client-Side Storage: The client is responsible for securely storing the token.

3. Mitigating the JWT Invalidation Problem: Refresh Tokens

The main drawback of JWTs—the difficulty of invalidation—is typically addressed with a refresh token pattern.

This involves using two types of tokens:

  • Access Token: A short-lived JWT (e.g., 15 minutes) sent with every API request. If it's stolen, the attacker only has a short window of time to use it.
  • Refresh Token: A long-lived token (e.g., 7 days) that is stored securely by the client and is sent only to a special endpoint to get a new access token when the old one expires.

This pattern provides a good balance between security and user experience, as the user doesn't need to log in again every 15 minutes.

Session Vs JWT: The Differences You May Not Know!

The ByteByteGo video has an excellent explanation of this two-token strategy. It's a critical concept in modern token-based authentication.

Watch the section from 03:52 to 05:06 to understand how access and refresh tokens work together.


4. A Head-to-Head Comparison

Let's summarize the core differences. This image provides a concise visual overview.

Session-Based Authentication vs. JSON Web Tokens (JWTs) Comparison
This image directly compares the two strategies. Sessions rely on server-side storage, making them stateful, while JWTs are self-contained and stored on the client, enabling a stateless architecture.

The following article provides a detailed comparison and a useful decision framework.

Token Based Authentication vs Session ...

The article 'Token Based Authentication vs Session Based Authentication' from SuperTokens offers great analogies and a clear breakdown of when to use each approach.

Please read the sections 'Comparative Analysis' and 'Choosing the Right Method'. Focus on the comparison across Security, Performance, and Scalability, and review the questions in the decision framework.

Here is a summary table based on what we've learned:

Feature Session-Based Authentication Token-Based Authentication (JWT)
State Stateful (Server stores session data) Stateless (Server stores nothing about the session)
Storage Session ID on client (cookie), session data on server Full token on client (e.g., local storage)
Scalability Harder to scale horizontally (requires a shared session store) Easy to scale horizontally
Revocation Trivial (delete session record on the server) Complex (token is valid until expiry; requires refresh tokens)
Performance Requires a database/cache lookup on every request Fast cryptographic verification (no DB lookup)
Typical Use Traditional monolithic web applications SPAs, mobile apps, microservices
Communication Relies on cookies, best for browser clients Uses Authorization header, client-agnostic
Test your understanding!

You are designing a system composed of many independent microservices (e.g., an authentication service, a product service, an order service). A user logs in via the authentication service. When they later make a request to the order service, how does that service know who the user is? Which authentication strategy would be more suitable here and why?

Show answer

Token-based authentication (JWT) would be more suitable.

When the user logs in, the authentication service would issue a JWT. The client would then include this JWT in the Authorization header of its request to the order service. The order service, knowing the shared secret key, can independently verify the token's signature and trust the user_id inside it without ever needing to contact the authentication service or a central database.

Using session-based authentication would be much more complex, as it would require all microservices to have access to a shared, centralized session store, creating a tight coupling between them and adding latency.


Conclusion

You now understand the fundamental architectural trade-offs between session-based and token-based authentication. Neither is universally "better"; the right choice depends entirely on your application's architecture and requirements.

Key Takeaways:

  • Session-based authentication is stateful. The server stores session data and uses a session ID (in a cookie) to identify users. It's simple for monolithic apps and allows for easy, instant session revocation. Its main drawback is the difficulty of scaling horizontally.
  • Token-based authentication (JWT) is stateless. The server stores nothing. A self-contained, signed token is stored by the client and sent with each request. It's highly scalable and ideal for APIs, mobile apps, and microservices. Its main drawback is the complexity of token revocation, which is often managed using a refresh token pattern.
  • The core trade-off is server control and simplicity (Sessions) versus scalability and flexibility (Tokens).

Preview of the Next Lesson:
Now that we have the theory, it's time to get practical. In the next lesson, we will implement our first token-based authentication system in Django REST Framework. We will start with DRF's built-in TokenAuthentication class. This approach uses a stateful token that is stored in the database, serving as a perfect stepping stone from sessions toward the fully stateless JWT model that we will implement later.