Session cookie configuration and manipulation with security features, expiration handling, and serialization capabilities.
The Cookie class manages session cookie properties and provides serialization methods.
/**
* Session cookie management class
* @param options - Cookie configuration options
*/
class Cookie {
constructor(options?: CookieOptions);
/** Cookie path (default: '/') */
path: string;
/** Max age in milliseconds or null for session cookies */
maxAge: number | null;
/** HttpOnly flag (default: true) */
httpOnly: boolean;
/** Secure flag for HTTPS only */
secure?: boolean;
/** Cookie domain */
domain?: string;
/** SameSite policy */
sameSite?: boolean | 'lax' | 'strict' | 'none';
/** Partitioned attribute for CHIPS */
partitioned?: boolean;
/** Priority level */
priority?: 'low' | 'medium' | 'high';
/** Original maxAge value for resetting */
originalMaxAge?: number;
/**
* Serialize cookie to Set-Cookie header value
* @param name - Cookie name
* @param val - Cookie value
* @returns Serialized cookie string
*/
serialize(name: string, val: string): string;
/**
* Return JSON representation of cookie
* @returns Cookie data object
*/
toJSON(): object;
/** Cookie data object (read-only) */
readonly data: object;
}
interface CookieOptions {
domain?: string;
expires?: Date;
httpOnly?: boolean;
maxAge?: number;
partitioned?: boolean;
path?: string;
priority?: 'low' | 'medium' | 'high';
sameSite?: boolean | 'lax' | 'strict' | 'none';
secure?: boolean | 'auto';
}Usage Examples:
const { Cookie } = require('express-session');
// Create cookie with options
const cookie = new Cookie({
maxAge: 1000 * 60 * 60, // 1 hour
httpOnly: true,
secure: true,
sameSite: 'strict'
});
// Access cookie properties
console.log(cookie.maxAge); // 3600000
console.log(cookie.httpOnly); // true
// Serialize cookie
const cookieString = cookie.serialize('sessionId', 'abc123');
console.log(cookieString); // 'sessionId=abc123; Path=/; HttpOnly; Secure; SameSite=Strict'Cookie expiration can be managed through expires date or maxAge duration.
interface CookieExpiration {
/** Expiration date setter */
set expires(date: Date | undefined);
/** Expiration date getter */
get expires(): Date | undefined;
/** Max age setter (in milliseconds) */
set maxAge(ms: number | Date | null);
/** Max age getter (time remaining in milliseconds) */
get maxAge(): number | null;
}Usage Examples:
// Set expiration using maxAge (recommended)
req.session.cookie.maxAge = 1000 * 60 * 30; // 30 minutes
// Set expiration using specific date
req.session.cookie.expires = new Date(Date.now() + 1000 * 60 * 60); // 1 hour
// Session cookie (expires when browser closes)
req.session.cookie.maxAge = null;
// Check remaining time
app.get('/session-time', (req, res) => {
const remaining = req.session.cookie.maxAge;
if (remaining) {
res.json({
remainingMs: remaining,
remainingMinutes: Math.floor(remaining / 1000 / 60)
});
} else {
res.json({ message: 'Session cookie (no expiration)' });
}
});Security-related cookie properties for protecting session data.
interface CookieSecurity {
/** HttpOnly flag prevents client-side JavaScript access */
httpOnly: boolean;
/** Secure flag requires HTTPS transmission */
secure?: boolean;
/** SameSite policy for CSRF protection */
sameSite?: boolean | 'lax' | 'strict' | 'none';
/** Partitioned attribute for third-party contexts */
partitioned?: boolean;
/** Priority level for cookie retention */
priority?: 'low' | 'medium' | 'high';
}Usage Examples:
// High security configuration
app.use(session({
secret: 'secret',
cookie: {
httpOnly: true, // Prevent XSS
secure: true, // HTTPS only
sameSite: 'strict', // Strong CSRF protection
maxAge: 1000 * 60 * 15 // 15 minutes
}
}));
// Third-party context configuration
app.use(session({
secret: 'secret',
cookie: {
secure: true,
sameSite: 'none', // Allow cross-site
partitioned: true // CHIPS support
}
}));
// Development configuration
app.use(session({
secret: 'secret',
cookie: {
secure: false, // Allow HTTP in development
httpOnly: true,
sameSite: 'lax' // Balanced CSRF protection
}
}));Control cookie scope through domain and path settings.
interface CookieScope {
/** Cookie domain (subdomain control) */
domain?: string;
/** Cookie path (URL path control) */
path: string;
}Usage Examples:
// Subdomain sharing
app.use(session({
secret: 'secret',
cookie: {
domain: '.example.com', // Available to all subdomains
path: '/'
}
}));
// Path-specific sessions
app.use('/admin', session({
secret: 'admin-secret',
name: 'admin.sid',
cookie: {
path: '/admin' // Only available under /admin path
}
}));
// API-specific sessions
app.use('/api', session({
secret: 'api-secret',
name: 'api.sid',
cookie: {
path: '/api',
httpOnly: true,
maxAge: 1000 * 60 * 60 // 1 hour for API sessions
}
}));Methods for converting cookie objects to strings and JSON.
interface CookieSerialization {
/**
* Serialize cookie to Set-Cookie header format
* @param name - Cookie name
* @param val - Cookie value
* @returns Set-Cookie header value
*/
serialize(name: string, val: string): string;
/**
* Convert cookie to JSON representation
* @returns Cookie data object
*/
toJSON(): object;
/** Get cookie data object */
readonly data: object;
}Usage Examples:
// Serialize cookie for custom header manipulation
app.use((req, res, next) => {
if (req.session && req.session.cookie) {
const cookieData = req.session.cookie.toJSON();
console.log('Cookie settings:', cookieData);
// Custom cookie serialization
const customCookie = req.session.cookie.serialize('custom-session', 'value');
res.setHeader('X-Custom-Session', customCookie);
}
next();
});
// Cookie data inspection
app.get('/cookie-info', (req, res) => {
if (req.session) {
res.json({
cookieData: req.session.cookie.data,
cookieJson: req.session.cookie.toJSON(),
maxAge: req.session.cookie.maxAge,
originalMaxAge: req.session.cookie.originalMaxAge
});
} else {
res.json({ error: 'No session found' });
}
});Modify cookie properties during request processing.
interface CookieManipulation {
/** Reset maxAge to original value */
originalMaxAge?: number;
}Usage Examples:
// Extend session for active users
app.use((req, res, next) => {
if (req.session && req.session.lastActivity) {
const timeSinceActivity = Date.now() - req.session.lastActivity;
// Extend session if user was active recently
if (timeSinceActivity < 1000 * 60 * 5) { // 5 minutes
req.session.cookie.maxAge = 1000 * 60 * 30; // Reset to 30 minutes
}
}
next();
});
// Reduce session time for sensitive operations
app.post('/sensitive-operation', (req, res) => {
// Temporarily reduce session timeout
const originalMaxAge = req.session.cookie.maxAge;
req.session.cookie.maxAge = 1000 * 60 * 5; // 5 minutes
performSensitiveOperation().then(() => {
// Restore original timeout
req.session.cookie.maxAge = originalMaxAge;
res.json({ message: 'Operation complete' });
});
});
// Dynamic cookie security based on content
app.use((req, res, next) => {
if (req.path.startsWith('/admin')) {
// Stricter security for admin pages
if (req.session && req.session.cookie) {
req.session.cookie.sameSite = 'strict';
req.session.cookie.secure = true;
}
}
next();
});Access the cookie object through the session.
interface SessionCookieAccess {
/** Cookie object associated with the session */
req.session.cookie: Cookie;
}Usage Examples:
// Cookie property access
app.get('/session-cookie', (req, res) => {
if (req.session) {
res.json({
cookieMaxAge: req.session.cookie.maxAge,
cookiePath: req.session.cookie.path,
cookieSecure: req.session.cookie.secure,
cookieHttpOnly: req.session.cookie.httpOnly,
cookieSameSite: req.session.cookie.sameSite
});
}
});
// Conditional cookie modification
app.use((req, res, next) => {
if (req.session && req.headers['user-agent'].includes('Mobile')) {
// Shorter sessions for mobile devices
req.session.cookie.maxAge = 1000 * 60 * 15; // 15 minutes
}
next();
});