Documentation
Cookie Management in LiteNode
LiteNode now includes a comprehensive cookie management system that makes it easy to set, read, and manage cookies in your web applications. This document covers how to use the cookie management features and best practices for working with cookies.
Enabling Cookie Parsing
To work with incoming cookies, you first need to enable the cookie parser middleware:
const app = new LiteNode()
// Enable cookie parsing
app.enableCookieParser()
After enabling the cookie parser, all incoming requests will have a cookies
object containing parsed cookie values.
Setting Cookies
You can set cookies using the setCookie
method on the response object:
app.get("/welcome", (req, res) => {
// Set a simple cookie that expires when the browser is closed
res.setCookie("greeting", "Hello there!")
res.txt("Welcome to our site!")
})
Cookie Options
You can pass various options when setting cookies:
res.setCookie("preferences", "dark-mode", {
maxAge: 30 * 24 * 60 * 60, // 30 days in seconds
path: "/",
httpOnly: true,
secure: true,
sameSite: "Strict",
})
Available options:
Option | Type | Description |
---|---|---|
maxAge |
number | Maximum age of the cookie in seconds |
expires |
Date | string | Specific expiration date |
path |
string | Path where the cookie is valid (defaults to '/') |
domain |
string | Domain where the cookie is valid |
secure |
boolean | Whether the cookie should only be sent over HTTPS |
httpOnly |
boolean | Whether the cookie should be inaccessible to JavaScript |
sameSite |
string | CSRF protection: 'Strict', 'Lax', or 'None' |
Reading Cookies
Once cookie parsing is enabled, you can access cookies from the request object:
app.get("/dashboard", (req, res) => {
const theme = req.cookies.theme || "light"
const username = req.cookies.username || "Guest"
res.render("dashboard", { theme, username })
})
Clearing Cookies
To remove a cookie, use the clearCookie
method:
app.get("/logout", (req, res) => {
res.clearCookie("username")
res.clearCookie("auth_token")
res.redirect("/login")
})
If you set the cookie with specific options like path
or domain
, you need to include the same options when clearing:
// Clear a cookie with a specific path
res.clearCookie("tracking", { path: "/products" })
// Clear a cookie set for a specific domain
res.clearCookie("preferences", { domain: "shop.example.com" })
Working with Signed Cookies
Signed cookies add an extra layer of security by ensuring that the cookie hasn't been tampered with. To use signed cookies, first create a signed cookie utility:
const app = new LiteNode()
app.enableCookieParser()
// Create a signed cookie utility with a strong secret
const signedCookies = app.createSignedCookies("your-secure-secret-key-at-least-16-chars-long")
Setting Signed Cookies
Use the signed cookie utility to set cookies that are cryptographically signed:
app.post("/login", async (req, res) => {
// Authenticate user (not shown)
const userId = "12345"
// Set a signed cookie
await signedCookies.setCookie(res, "userId", userId, {
maxAge: 24 * 60 * 60, // 1 day
httpOnly: true,
secure: true,
})
res.redirect("/dashboard")
})
Reading and Verifying Signed Cookies
To verify signed cookies:
app.get("/profile", async (req, res) => {
// Get and verify the signed cookie
const userId = await signedCookies.getCookie(req, "userId")
if (!userId) {
// Cookie was invalid or tampered with
return res.redirect("/login")
}
// Continue with the verified userId
const userData = await getUserData(userId)
res.render("profile", userData)
})
Security Best Practices
Always use
httpOnly
for sensitive cookies to prevent access from JavaScript (protects against XSS attacks)Set
secure: true
in production to ensure cookies are only sent over HTTPSUse
sameSite: 'Strict'
or'Lax'
to protect against CSRF attacksUse signed cookies for any cookie data that needs integrity protection
Keep cookie data minimal - store only what you need (like session IDs, not entire user objects)
Set appropriate expirations - use the shortest practical lifetime for your cookies
Use specific paths when applicable to limit cookie scope
API Reference
Response Methods
res.setCookie(name, value, options)
Sets a cookie with the given name, value, and options.
Parameters:
name
(string): The name of the cookievalue
(string): The value of the cookieoptions
(object, optional): Cookie options
Returns: The response object for chaining
See Setting Cookies section.
res.getCookies()
Gets all cookies set on the response.
- Returns: Array of cookie strings
app.get("/checkout", (req, res) => {
// Set multiple cookies
res.setCookie("cartId", "12345")
res.setCookie("tracking", "checkout-flow")
// Get all cookies that have been set on this response
const cookies = res.getCookies()
console.log("Cookies set:", cookies)
// Output: Cookies set: ['cartId=12345; Path=/', 'tracking=checkout-flow; Path=/']
res.render("checkout")
})
res.clearCookie(name, options)
Clears a cookie by setting its expiration in the past.
Parameters:
name
(string): The name of the cookie to clearoptions
(object, optional): Cookie options (path and domain must match the original cookie)
Returns: The response object for chaining
See Clearing Cookies section.
LiteNode Methods
app.enableCookieParser()
Enables cookie parsing middleware.
- Returns: The LiteNode instance for chaining
See Enabling Cookie Parsing section.
app.createSignedCookies(secret)
Creates utilities for working with signed cookies.
Parameters:
secret
(string): Secret key used for signing cookies (at least 16 characters)
Returns: Object with signed cookie utilities:
sign(value)
: Signs a valueverify(signedValue)
: Verifies a signed valuesetCookie(res, name, value, options)
: Sets a signed cookiegetCookie(req, name)
: Gets and verifies a signed cookie
See Working with Signed Cookies section.
Request Properties
req.cookies
Object containing all cookies sent by the client, with cookie names as keys and values as strings.
Examples
Basic Cookie Example
import { LiteNode } from "litenode"
const app = new LiteNode()
app.enableCookieParser()
// Set a cookie on one route
app.get("/set-language", (req, res) => {
const lang = req.queryParams.get("lang") || "en"
res.setCookie("language", lang, { maxAge: 365 * 24 * 60 * 60 }) // 1 year
res.redirect("/")
})
// Read the cookie on another route
app.get("/", (req, res) => {
const language = req.cookies.language || "en"
res.render("home", { language })
})
app.startServer(3000)
Authentication Example with Signed Cookies
import { LiteNode } from "litenode"
const app = new LiteNode()
app.enableCookieParser()
const signedCookies = app.createSignedCookies("my-secure-secret-key-change-me")
// Mock user database
const users = {
user1: { password: "pass1", name: "Alice" },
user2: { password: "pass2", name: "Bob" },
}
// Login route
app.post("/login", async (req, res) => {
const { username, password } = req.body
// Basic authentication
if (users[username] && users[username].password === password) {
// Set a signed session cookie
await signedCookies.setCookie(res, "session", username, {
maxAge: 3600, // 1 hour
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "Lax",
})
return res.redirect("/dashboard")
}
res.status(401).txt("Invalid credentials")
})
// Protected route with authentication check
app.get("/dashboard", async (req, res) => {
const username = await signedCookies.getCookie(req, "session")
if (!username || !users[username]) {
return res.redirect("/login")
}
const user = users[username]
res.render("dashboard", { name: user.name })
})
// Logout route
app.get("/logout", (req, res) => {
res.clearCookie("session")
res.redirect("/login")
})
app.startServer(3000)
User Preferences Example
import { LiteNode } from "litenode"
const app = new LiteNode()
app.enableCookieParser()
// Save user preferences in a cookie
app.post("/save-preferences", (req, res) => {
const { theme, fontSize, notifications } = req.body
// Create a JSON string of preferences
const preferences = JSON.stringify({
theme: theme || "light",
fontSize: fontSize || "medium",
notifications: notifications === "on",
})
// Save preferences in a cookie that lasts 1 year
res.setCookie("userPrefs", preferences, {
maxAge: 365 * 24 * 60 * 60,
path: "/",
})
res.redirect("/settings?saved=true")
})
// Apply preferences to all pages
app.use((req, res) => {
// Default preferences
let userPrefs = {
theme: "light",
fontSize: "medium",
notifications: true,
}
// Try to get preferences from cookie
if (req.cookies.userPrefs) {
try {
userPrefs = JSON.parse(req.cookies.userPrefs)
} catch (e) {
// Invalid JSON, stick with defaults
}
}
// Add preferences to req object for use in route handlers
req.userPreferences = userPrefs
})
app.get("/settings", (req, res) => {
const saved = req.queryParams.get("saved") === "true"
res.render("settings", {
preferences: req.userPreferences,
saved,
})
})
app.startServer(3000)
By following the best practices and using the cookie management features provided by LiteNode, you can create secure and efficient web applications that properly handle client state through cookies.
Content
- Enabling Cookie Parsing
- Setting Cookies
- Reading Cookies
- Clearing Cookies
- Working with Signed Cookies
- Security Best Practices
- API Reference
- Response Methods
- LiteNode Methods
- Request Properties
- Examples