The Coat Check Analogy
At a fancy restaurant:
- You give your coat to the coat check
- They give you a ticket (number)
- Later, you show the ticket
- They return your coat
Sessions work the same way. Server stores your data, gives you a ticket (session ID), and retrieves your data when you show the ticket.
What Are Sessions?
Session = Server-side storage linked to a user
You: Here's my session ID (abc123)
Server: Let me look up abc123...
Server: Ah, you're Alice, logged in, have 3 items in cart
Data stored on server.
Typically only an ID travels to the client.
How Sessions Work
Creating a Session
1. User logs in successfully
2. Server creates session:
{ id: "abc123", user: "Alice", cart: [] }
3. Server stores session (memory, database, Redis)
4. Server sends session ID in cookie
5. Browser stores cookie
Using a Session
1. Browser sends cookie with session ID
2. Server receives: session=abc123
3. Server looks up: sessions["abc123"]
4. Finds: { user: "Alice", cart: [...] }
5. Server knows who you are!
Destroying a Session
Logout:
1. Server deletes session from storage
2. Server tells browser to delete cookie
3. Session ID no longer valid
Session vs Cookie
Cookie:
Data stored in BROWSER
Sent to server each request
Size limits are relatively small
Client can read/modify
Session:
Data stored on SERVER
Only ID stored in cookie
Unlimited size
Client typically can't see/modify the server-side data
Security Comparison
Cookie: { user: "alice", isAdmin: true }
Client can change isAdmin to true!
Session: { id: "abc123" } → Server lookup
Client only has meaningless ID.
Data stays on the server.
Session Storage Options
In-Memory
Stored in server RAM.
Pros: Fast
Cons: Lost on server restart, doesn't scale (single server)
Good for: Development, simple apps
Database
Stored in PostgreSQL, MySQL, etc.
Pros: Persistent, scalable
Cons: Slower (disk I/O)
Good for: When sessions must survive restarts
Redis/Memcached
In-memory data store, shared.
Pros: Fast, scalable, expires naturally
Cons: Extra infrastructure
Good for: Production, multiple servers
Common choice for production.
Session ID Security
Making IDs Hard to Guess
Session ID should be:
✓ Random (not guessable)
✓ High entropy
✓ Cryptographically generated
Bad: session_1, session_2
Good: a7d9f3k2x8m1p5q9...
Session Hijacking
Attacker gets your session ID.
Attacker becomes you!
Prevention:
- HTTPS only
- HttpOnly cookies
- Regenerate ID after login
- Short session lifetime
Session Fixation
Attacker sets your session ID before login.
You log in, attacker uses same ID.
Prevention:
- Regenerate session ID after login
- Don't accept session IDs in URLs
Session Lifecycle
┌─────────────────────────────────────────┐
│ User visits site │
│ │
│ ┌─────────────────────────────────────┐ │
│ │ New session created │ │
│ │ ID stored in cookie │ │
│ └─────────────────────────────────────┘ │
│ │
│ User browses, uses app │
│ │
│ ┌─────────────────────────────────────┐ │
│ │ Session data updated │ │
│ │ Expiry extended (activity) │ │
│ └─────────────────────────────────────┘ │
│ │
│ User logs out OR timeout │
│ │
│ ┌─────────────────────────────────────┐ │
│ │ Session destroyed │ │
│ │ Cookie deleted │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────┘
Session Timeout
Absolute Timeout
Session dies after a fixed maximum lifetime.
Security: Limits exposure window.
Idle Timeout
Session dies after a period of inactivity.
Extended with each request.
Balance: Security + convenience.
Sessions vs JWT
| Aspect | Sessions | JWT |
|---|---|---|
| Storage | Server-side | Client-side (token) |
| Scalability | Needs shared storage | Stateless |
| Revocation | Easy (delete from store) | Hard (need blacklist) |
| Data access | Server only | Client can decode |
| Size | Cookie small, data large | Token can be large |
Sessions: More control, more server work
JWT: Stateless, harder to revoke
Scaling Sessions
The Problem
User hits Server A → Session created on A
User hits Server B → Where's my session?
Solutions
1. Sticky sessions:
Load balancer sends user to same server.
Simple but limits scaling.
2. Shared session store (Redis):
All servers read/write to Redis.
Scales well.
3. Stateless (JWT):
No server-side sessions.
Client holds everything.
Common Mistakes
1. Storing Too Much in Session
Session: { user, preferences, history, friends, ... }
Session bloat = Slow!
Store ID references, fetch when needed.
2. Long Session Timeout
Session lasts forever?
Security risk!
Use reasonable timeouts.
3. Not Regenerating on Login
Same session ID before and after login.
Session fixation vulnerability!
Regenerate session ID after authentication.
FAQ
Q: When to use sessions vs JWT?
Sessions: Traditional apps, easier revocation JWT: Microservices, stateless architecture
Q: Can sessions work without cookies?
Yes, you can put a session ID in a header or (less commonly) a URL. Cookies are a common approach, and avoiding URLs can reduce accidental leakage (for example via logs or referrers).
Q: How long should sessions last?
It depends on risk and usability. High-risk apps often use shorter idle timeouts; lower-risk apps may use longer timeouts.
Q: What happens when session storage is full?
Old sessions expire/evict. Configure TTL properly.
Summary
Sessions store user data on the server, identified by a session ID sent in a cookie.
Key Takeaways:
- Server stores data, client holds only ID
- Often reduces exposure compared to putting user data directly in the client
- Session ID should be random and hard to guess
- Use a shared session store (like Redis/Memcached) in production
- Regenerate ID after login
- Set appropriate timeouts
Sessions are the traditional way to maintain state across requests!
Related Concepts
Leave a Comment
Comments (0)
Be the first to comment on this concept.
Comments are approved automatically.