Skip to content

Cookie auth with client-sessions (+ array-of-paths guard) #11

Description

@chriscalo

Part of #7. Cookie-based auth via client-sessions (encrypted, signed cookie — no server-side store), living in the api express() app. Protect page routes with an array-of-paths guard rather than per-route checks (Express Core).

Sessions (in src/api/index.js)

import express from "express";
import nocache from "nocache";
import sessions from "client-sessions";

const server = express();
export default server;

server.use(sessions({
  cookieName: "session",
  secret: process.env.SESSION_SECRET,        // required, dev + prod
  duration: 24 * 60 * 60 * 1000,             // 24h
  activeDuration: 5 * 60 * 1000,             // sliding 5m
  cookie: { httpOnly: true, secure: true, sameSite: "lax" },
}));

server.post("/api/login", express.json(), (req, res) => {
  // validate credentials →
  req.session.user = { id, name };
  res.json({ ok: true });
});
server.post("/api/logout", (req, res) => { req.session.reset(); res.json({ ok: true }); });

Protect routes — array of paths + nocache() + guard

server.use(["/budget", "/goals", "/settings"], nocache(), signinRequired);

function signinRequired(req, res, next) {
  if (!req.session?.user) return res.status(401).json({ error: "unauthorized" });
  next();
}

Notes

  • client-sessions is stateless — no store to configure, but the cookie is size-limited (~4KB); keep session payloads small.
  • SESSION_SECRET must be set in dev (.env) and prod.

Tasks

  • Add client-sessions + nocache deps
  • Mount sessions(...) in src/api/index.js
  • /api/login + /api/logout
  • signinRequired guard mounted across the protected-paths array
  • Document SESSION_SECRET

Acceptance

  • Login sets an encrypted session cookie; signinRequired blocks unauthenticated requests (401) on protected paths; logout resets the session. Identical in dev and prod.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions