Cookie Plugin
Provides comprehensive cookie parsing and management. Automatically parses incoming cookies and provides convenient methods for setting and clearing cookies on responses.
Quick Start
import { Server } from "balda";
const server = new Server({
plugins: {
cookie: {
secret: "your-secret-key",
},
},
});
Configuration
cookie: {
secret: 'your-secret-key', // Required for signed cookies
parse: true, // Enable cookie parsing (default: true)
sign: false, // Enable cookie signing (default: false)
defaults: {
path: '/', // Cookie path (default: '/')
httpOnly: true, // HttpOnly flag (default: true)
secure: false, // Secure flag (default: false)
sameSite: 'Lax' // SameSite attribute (default: 'Lax')
}
}
Production Configuration
cookie: {
secret: process.env.COOKIE_SECRET,
sign: true,
defaults: {
httpOnly: true,
secure: true, // HTTPS only
sameSite: 'Strict',
domain: '.myapp.com'
}
}
Usage
Setting Cookies
@controller("/auth")
export class AuthController {
@post("/login")
async login(req: Request, res: Response) {
const user = await validateUser(req.body.username, req.body.password);
if (user) {
// Set cookie
res.cookie("sessionId", user.sessionId, {
maxAge: 24 * 60 * 60 * 1000, // 24 hours
httpOnly: true,
secure: true,
});
res.json({ message: "Login successful" });
}
}
@post("/logout")
async logout(req: Request, res: Response) {
// Clear cookie
res.clearCookie("sessionId");
res.json({ message: "Logout successful" });
}
}
Reading Cookies
@get('/profile')
async getProfile(req: Request, res: Response) {
const sessionId = req.cookies.sessionId;
const theme = req.cookies.theme || 'light';
if (!sessionId) {
return res.unauthorized({ error: 'No session found' });
}
const user = await getUserBySession(sessionId);
res.json({ user, theme });
}
Setting Multiple Cookies
@post('/preferences')
async setPreferences(req: Request, res: Response) {
const { theme, language, timezone } = req.body; // Automatically parsed when using body parser middleware with json setting
res
.cookie('theme', theme, { maxAge: 365 * 24 * 60 * 60 * 1000 })
.cookie('language', language, { maxAge: 365 * 24 * 60 * 60 * 1000 })
.cookie('timezone', timezone, { maxAge: 365 * 24 * 60 * 60 * 1000 })
.json({ message: 'Preferences updated' });
}
Cookie Options
maxAge
Cookie expiration in milliseconds:
res.cookie("name", "value", {
maxAge: 24 * 60 * 60 * 1000, // 24 hours
});
httpOnly
Prevent JavaScript access (recommended for security):
res.cookie("sessionId", value, {
httpOnly: true, // Cannot be accessed via JavaScript
});
secure
Only send over HTTPS:
res.cookie("sessionId", value, {
secure: true, // HTTPS only
});
sameSite
CSRF protection:
res.cookie("name", value, {
sameSite: "Strict", // or 'Lax' or 'None'
});
domain
Cookie domain:
res.cookie("name", value, {
domain: ".myapp.com", // Works for all subdomains
});
path
Cookie path:
res.cookie("name", value, {
path: "/api", // Only sent to /api routes
});
Signed Cookies
Enable signing for tamper-proof cookies:
// Configuration
cookie: {
secret: 'your-secret-key',
sign: true
}
// Set signed cookie
res.cookie('userId', user.id, {
signed: true,
httpOnly: true
});
// Read signed cookie
const userId = req.signedCookies.userId;
Security Best Practices
Session Cookies
res.cookie("sessionId", sessionId, {
httpOnly: true, // Prevent XSS
secure: true, // HTTPS only
sameSite: "Strict", // Prevent CSRF
maxAge: 24 * 60 * 60 * 1000,
});
Authentication Tokens
res.cookie("authToken", token, {
httpOnly: true,
secure: true,
sameSite: "Strict",
signed: true, // Prevent tampering
});
User Preferences
res.cookie("theme", "dark", {
httpOnly: false, // Allow JavaScript access
secure: true,
sameSite: "Lax",
maxAge: 365 * 24 * 60 * 60 * 1000, // 1 year
});
Environment-Based Configuration
const isProduction = process.env.NODE_ENV === "production";
const server = new Server({
plugins: {
cookie: {
secret: process.env.COOKIE_SECRET,
sign: isProduction,
defaults: {
httpOnly: true,
secure: isProduction,
sameSite: isProduction ? "Strict" : "Lax",
},
},
},
});
Common Patterns
Session Management
cookie: {
secret: process.env.SESSION_SECRET,
sign: true,
defaults: {
httpOnly: true,
secure: true,
sameSite: 'Strict',
maxAge: 24 * 60 * 60 * 1000
}
}
Remember Me
res.cookie("rememberMe", token, {
httpOnly: true,
secure: true,
sameSite: "Strict",
maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
});
Analytics Tracking
res.cookie("tracking", trackingId, {
httpOnly: false,
secure: true,
sameSite: "Lax",
maxAge: 365 * 24 * 60 * 60 * 1000,
});