Session
The Session class in Harpia provides a simple, secure way to manage stateful data across multiple HTTP requests from the same client. It handles storing the session data on the server and synchronizing the session ID via cookies.
Initialization
To use sessions, you need to instantiate the Session class. By default, it uses an in-memory store and sets the cookie name to session_id.
import harpia, { Session } from "@harpiats/core";
const app = harpia();
const session = new Session();
Options
You can customize the store and the cookie name by passing an options object:
import { RedisStore } from "./my-custom-store";
const session = new Session({
cookieName: "myapp_session",
store: new RedisStore() // Must implement the Store interface
});
For a detailed guide on how to implement custom storage engines, please refer to the Stores documentation.
Creating a Session
When a user logs in or performs an action that requires a session, you can create one using the create method. This method generates a unique UUID, stores the data, and returns the session ID.
You must then manually set the cookie in the response using setCookie.
app.post("/login", async (req, res) => {
const userData = { id: 1, name: "John Doe", role: "admin" };
// 1. Create the session in the store
const sessionId = await session.create(userData);
// 2. Set the session ID in the client's cookie
session.setCookie(res, sessionId, {
httpOnly: true,
secure: true,
maxAge: 86400 // 1 day
});
res.json({ message: "Logged in successfully" });
});
Retrieving Session Data
To access session data in subsequent requests, you can use the fromRequest helper method. It automatically reads the cookie from the Request object and fetches the data from the store.
app.get("/profile", async (req, res) => {
const userData = await session.fromRequest(req);
if (!userData) {
return res.status(401).send("Unauthorized");
}
res.json({ profile: userData });
});
WebSockets
You can also retrieve session data directly from a WebSocket connection using fromWebSocket:
app.ws("/chat", {
async open(ws) {
const userData = await session.fromWebSocket(ws);
if (!userData) {
ws.close();
return;
}
console.log(`${userData.username} connected`);
}
});
Updating a Session
If you need to add or modify data in an existing session (e.g., updating user preferences), use the update method. It merges the new data with the existing data.
app.patch("/preferences", async (req, res) => {
const sessionId = req.cookies.get("session_id");
if (sessionId) {
const newPrefs = await req.json();
await session.update(sessionId, { preferences: newPrefs });
res.send("Preferences updated");
}
});
Deleting a Session
When a user logs out, you should destroy the session. The delete method removes the data from the server-side store and also clears the cookie from the client’s browser.
app.post("/logout", async (req, res) => {
const sessionId = req.cookies.get("session_id");
if (sessionId) {
// Deletes from store AND tells the browser to clear the cookie
await session.delete(sessionId, res);
}
res.send("Logged out");
});
Memory Store
By default, Harpia uses MemoryStore. While this is great for development, it will reset every time you restart the server and does not share state across multiple server instances. For production, you should implement and inject a persistent store like Redis or a database.