TL;DR
A session tracks a user's logged-in state across multiple requests. When you log in, the server creates a session, stores user data, and gives you a session ID (usually in a cookie). Each request includes this ID, letting the server look up who you are. Sessions are easier to invalidate than JWTs but require server-side storage.
The Simple Explanation
HTTP is stateless. Each request is independent. Sessions add memory. When you log in, the server says "here's your membership card" (session ID). You show this card with each request. The server looks it up and knows it's you, what your permissions are, and your preferences.
How Sessions Work
- User logs in with username/password
- Server validates credentials
- Server creates session, stores user data
- Server sends session ID in a cookie
- Browser sends cookie with each request
- Server looks up session to identify user
Session vs JWT
| Aspect | Sessions | JWTs |
|---|---|---|
| Storage | Server-side | Client-side (in token) |
| Revocation | Instant (delete from store) | Difficult (wait for expiry) |
| Scaling | Need shared session store | Stateless, scales easily |
| Size | Small cookie (just ID) | Larger (contains data) |
Session Security Best Practices
// Express.js example app.use(session({ secret: process.env.SESSION_SECRET, cookie: { httpOnly: true, // Prevents JavaScript access secure: true, // HTTPS only sameSite: 'strict', // Prevents CSRF maxAge: 3600000 // 1 hour expiry }, resave: false, saveUninitialized: false }));
Security Checklist
- httpOnly: Prevent XSS from stealing sessions
- secure: Only send over HTTPS
- SameSite: Prevent CSRF attacks
- Regenerate on login: Prevent session fixation
- Set expiration: Limit how long sessions last
- Use secure storage: Redis, not memory in production
What is the difference between sessions and JWTs?
Sessions store user data on the server and give clients just an ID. JWTs store user data in the token itself. Sessions are easier to invalidate instantly. JWTs are stateless and scale better but cannot be revoked until they expire. Choose based on your needs.
How do I prevent session hijacking?
Use httpOnly cookies so JavaScript cannot read the session ID. Use secure flag to only send over HTTPS. Set SameSite attribute to prevent CSRF. Regenerate session ID after login. Implement session timeout and absolute expiration. Consider binding sessions to IP or user agent.
Where should I store session data?
For small apps, memory or the database works. For production apps with multiple servers, use Redis or a similar distributed cache. This allows any server to access any session and provides fast lookups. Memory storage breaks when you scale to multiple servers.