KAHIBARO
Discord Login Register

2.14. Sessions

Why Sessions Exist

HTTP is a stateless protocol. Each request is independent. The server does not remember that the same browser sent a previous request.

Yet, most web apps need to remember things across requests, for example:

A session is a way to store data on the server and connect it to a particular client across multiple requests.

You can think of it as:

So the pattern is:

  1. Server creates a session and assigns it a session ID
  2. Server sends the session ID to the client (usually via a cookie)
  3. Client sends the session ID back with every request
  4. Server looks up session data using that ID

A session allows a stateless protocol (HTTP) to support stateful interactions by storing state on the server and identifying it with a session ID from the client.

Sessions vs Cookies

Sessions and cookies often appear together, but they are not the same thing.

Core Difference

FeatureCookiesSessions
Stored whereIn the browserOn the server
Who controls dataMainly the client (but set by server)The server
What is storedSmall pieces of textAny server data (objects, lists, flags, etc.)
SecurityVisible to the userHidden from user, more secure
Typical usagePreferences, session IDs, simple flagsUser login, shopping cart, temporary state

With sessions:

Example:

text
  abc123xyz => {
      "user_id": 10,
      "role": "admin",
      "cart": [101, 202]
  }

The browser never sees the actual data. It only knows the ID.

How Sessions Work in the Request-Response Cycle

Let us walk through a typical login flow using sessions.

Step 1: User Logs In

  1. User submits login form: POST /login with username and password.
  2. Server checks credentials.
  3. If valid:
    • Create a new session record on the server
    • Generate a random session_id, for example: d8a2f117-5e5a-4c0a-9a8f
    • Store session data on the server:
python
     sessions["d8a2f117-5e5a-4c0a-9a8f"] = {
         "user_id": 42,
         "username": "alice"
     }
  1. Server sends a response with a Set-Cookie header:
http
   HTTP/1.1 200 OK
   Set-Cookie: session_id=d8a2f117-5e5a-4c0a-9a8f; HttpOnly; Secure; Path=/;
  1. Browser stores this cookie.

Step 2: Browser Sends Session Cookie on Each Request

Next request, for example GET /profile:

http
GET /profile HTTP/1.1
Host: example.com
Cookie: session_id=d8a2f117-5e5a-4c0a-9a8f

On the server:

  1. Read session_id from cookies
  2. Look it up in session storage:
python
   session = sessions.get("d8a2f117-5e5a-4c0a-9a8f")
  1. If found, server knows the user is logged in as user_id=42
  2. Server can then load the profile for user 42

If there is no session for that ID (for example expired or invalid), the server treats the request as from an anonymous user.

Step 3: Modifying Session Data

On POST /cart/add:

python
  session = sessions.get("d8a2f117-5e5a-4c0a-9a8f")
  session["cart"].append(new_item_id)

From the browser side, nothing changes. It still only sends session_id.

Step 4: Logging Out and Session Destruction

On POST /logout:

  1. Server reads the session_id cookie
  2. Deletes the session from storage:
python
   sessions.pop("d8a2f117-5e5a-4c0a-9a8f", None)
  1. Optionally tells browser to delete the cookie:
http
   Set-Cookie: session_id=deleted; Max-Age=0; Path=/;

From then on, the session_id no longer points to valid data, so the user is effectively logged out.

Session Storage Options

Sessions can be stored in different places on the server side. Each option has tradeoffs.

Storage TypeWhere it livesProsCons
In memoryRAM of the app serverVery fast, simpleLost on restart, hard with multiple servers
File basedLocal diskSimple, persists across restartsSlower, not good for many servers
DatabaseRelational / NoSQL DBPersistent, scalableAdds DB load and some latency
Cache storeRedis, MemcachedVery fast, good for scalingExtra infrastructure, sessions might be lost

For a single small app:

For production apps with many users and multiple servers:

Example of how mapping works conceptually:

session_idsession data
d8a2f117-5e5a-4c0a-9a8f{"user_id": 42, "cart": [101, 202]}
5d44ec83-d163-476b-b658-7c8fbfb6{"user_id": 19, "theme": "dark"}

This table can live in memory, Redis, PostgreSQL, etc.

Session IDs and Security

The entire security of sessions depends on the session ID. If an attacker gets it, they can act as that user.

So session IDs must be:

The session ID is as sensitive as a password for the lifetime of the session. If someone steals it, they can hijack the session and impersonate the user.

Common protections:

Session Lifetime and Expiration

Sessions should not live forever.

Types of expiration

  1. Absolute expiration
    • Session expires after a fixed time, for example 24 hours from creation
    • Even if user is active, session eventually ends
  2. Idle timeout
    • Session expires if there is no activity for a period, for example 30 minutes
    • Each request can reset the timer
  3. Manual invalidation
    • The server can invalidate sessions explicitly
    • For example on logout, password change, admin action

On the server, you might store timestamps:

python
session = {
    "user_id": 42,
    "created_at": 1724700000,   # Unix timestamp
    "last_seen": 1724706000
}

Then on each request:

  1. Check created_at and last_seen
  2. If too old, delete session and force login

Example rule:

A common policy:

  • Absolute expiration: $24 \text{ hours}$
  • Idle timeout: $30 \text{ minutes}$
    Whichever limit is hit first ends the session.

Stateless vs Stateful Sessions

There are two broad approaches to sessions.

1. Stateful Sessions

This is what we have described so far:

Characteristics:

Most classic web frameworks (Django, Rails, etc.) use stateful sessions.

2. Stateless Sessions

Here, the session data itself is stored on the client side, typically in a signed or encrypted token such as a JSON Web Token (JWT).

Characteristics:

For this chapter, the main idea is the contrast:

AspectStateful sessionsStateless sessions
Data livesOn the serverIn token on client
Client storesSession IDWhole session token
ScalingNeeds shared store or stickinessEasier to scale, no shared store needed
InvalidationEasy, delete on serverHarder, often requires blacklists

You will see more details when you study tokens and JWTs later.

Session Use Cases and Examples

To solidify the concept, here are some typical session uses.

Example 1: Remembering Login State

Without sessions:

With sessions:

python
  session["user_id"] = user.id
  session["username"] = user.username
python
  if "user_id" not in session:
      return redirect("/login")

The framework hides the cookie and lookup details from you. You work with the session object.

Example 2: Shopping Cart

You can implement a simple cart without requiring the user to log in.

  1. When a new visitor arrives without a session, create one and assign an ID.
  2. Store cart items in session:
python
   session.setdefault("cart", [])
   session["cart"].append(product_id)
  1. When displaying cart:
python
   cart_items = session.get("cart", [])

If the user closes the browser and returns before session expiration, the cart is still there.

Example 3: Flash Messages

Some frameworks use sessions for one-time messages, for example:

Implementation idea:

  1. On POST /profile/update success:
python
   session["flash"] = "Profile updated successfully."
  1. On next page load:
python
   message = session.pop("flash", None)  # read and remove
  1. Show message if it exists

This uses the session as temporary storage between two requests.

Common Pitfalls with Sessions

Beginners often make similar mistakes when working with sessions.

1. Storing Too Much Data

Sessions are for small pieces of data. Avoid storing:

Problems:

Keep it small:

2. Relying Only on Sessions for Security

Session checks are important, but you still need:

A valid session does not mean the request is safe.

3. Forgetting to Clear Sessions on Sensitive Changes

If a user:

You might want to:

Otherwise, old sessions might still be valid.

4. Not Using HTTPS with Session Cookies

Sending session cookies over plain HTTP exposes them to eavesdropping.

Always protect real user sessions with HTTPS and the Secure cookie flag.

Summary

Understanding sessions gives you the missing piece for building web applications that feel persistent and personalized on top of a stateless protocol.

Views: 9

Comments

Please login to add a comment.

Don't have an account? Register now!