Session‐Based Authentication and Authorization - sonuprajapati15/Authentication-Authorization GitHub Wiki
Session-based authentication is a method where a server creates and manages user sessions after successful login. These sessions are typically stored in memory, a database, or a caching layer (e.g., Redis). Unlike token-based authentication (JWT), session-based authentication is stateful, meaning the server tracks session information.
✅ Users can register and log in using credentials.
✅ Upon successful login, a session is created and stored on the server.
✅ Clients receive a session ID (stored in cookies) to authenticate future requests.
✅ Users can log out, invalidating the session.
✅ Session expiration and automatic renewal mechanisms.
⚡ Security – Use secure cookies, prevent session hijacking (e.g., CSRF, XSS attacks).
⚡ Scalability – Session storage should support distributed architectures.
⚡ Performance – Optimize session retrieval using in-memory caching (e.g., Redis).
⚡ Availability – Sessions should persist across failures (consider database-backed storage).
⚡ Compliance – GDPR and data privacy considerations for session storage.
- Client (Browser/App) – Sends login credentials, stores session cookie.
- Authentication Server – Handles login/logout, generates session IDs, and manages session storage.
- Session Store – Stores session data (in-memory cache like Redis or a database).
- Resource Server – Validates session IDs and grants access to protected resources.
- User logs in – Sends credentials to the authentication server.
- Session Creation – Server validates credentials and creates a session (stores in Redis/DB).
- Session Cookie – A session ID is sent to the client in a secure, HTTP-only cookie.
- Authenticated Requests – The client includes the session cookie in future requests.
- Session Validation – The server checks session validity before granting access.
- Logout & Expiry – The user logs out, or the session expires, and it’s removed from storage.
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(255) UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE sessions (
session_id UUID PRIMARY KEY,
user_id INT REFERENCES users(id) ON DELETE CASCADE,
expires_at TIMESTAMP NOT NULL
);
Method | Endpoint | Description |
---|---|---|
POST | /login | Authenticate user and start a session |
GET | /protected | Access protected resources (requires session) |
POST | /logout | Destroy the session |
View or edit this diagram in Whimsical.
npm install express express-session bcrypt redis connect-redis dotenv
require("dotenv").config();
const express = require("express");
const session = require("express-session");
const RedisStore = require("connect-redis").default;
const redis = require("redis");
const bcrypt = require("bcrypt");
const app = express();
const redisClient = redis.createClient({ url: process.env.REDIS_URL });
app.use(express.json());
app.use(
session({
store: new RedisStore({ client: redisClient }),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: { httpOnly: true, secure: false, maxAge: 30 * 60 * 1000 }, // 30 min expiry
})
);
// Mock database
const users = [{ id: 1, username: "user1", passwordHash: bcrypt.hashSync("password", 10) }];
// Login Route
app.post("/login", async (req, res) => {
const { username, password } = req.body;
const user = users.find((u) => u.username === username);
if (!user || !(await bcrypt.compare(password, user.passwordHash))) {
return res.status(401).json({ message: "Invalid credentials" });
}
req.session.userId = user.id;
res.json({ message: "Login successful" });
});
// Protected Route
app.get("/protected", (req, res) => {
if (!req.session.userId) {
return res.status(401).json({ message: "Unauthorized" });
}
res.json({ message: "Access granted" });
});
// Logout Route
app.post("/logout", (req, res) => {
req.session.destroy(() => res.json({ message: "Logged out" }));
});
app.listen(3000, () => console.log("Server running on port 3000"));
- In-memory (Fast, non-persistent) – Redis, Memcached.
- Database (Persistent, but slower) – PostgreSQL, MySQL.
- Fixed expiration (e.g., 30 minutes).
- Sliding expiration (session refreshes on activity).
- Manual revocation (e.g., logout or forced session termination).
Factor | Trade-off |
---|---|
Scalability | Stateful sessions require session replication or sticky sessions in load-balanced setups. |
Security | Secure cookies prevent access from JavaScript; CSRF protection is necessary. |
Performance | Redis improves session lookup times, but adds infrastructure complexity. |
Persistence | Storing sessions in a database ensures durability but reduces speed. |
Session-based authentication is a stateful approach that requires careful session storage management. It is a great choice for monolithic applications and scenarios where security is a priority, but it has scalability challenges compared to token-based authentication (JWT).