Signed session

Login action sets an HMAC-signed cookie; loader verifies the signature on every request. Tampered values fail constant-time comparison and the loader treats the request as anonymous. HttpOnly keeps the token out of JS.

Status

Source

// HMAC-signed cookie. Login action sets it; loader verifies the
         // signature on every request before trusting the name; logout clears it.

    import { createHmac, timingSafeEqual } from "node:crypto";

    const SECRET = process.env.SESSION_SECRET!;

    function sign(payload: string) {
                return createHmac("sha256", SECRET).update(payload).digest("base64url");
    }
    export async function loader({ request }: { request: Request }) {
                const cookie = request.headers.get("cookie") ?? "";
                const token = parseCookies(cookie)["demo_session_token"];
                if (!token) return { session: null };
                // verify signature, return null on tamper
                return { session: verify(token) };
    }
    export async function action({ request }: { request: Request }) {
                const form = await request.formData();
                const name = String(form.get("name") ?? "");
                return new Response(null, {
                                status: 200,
                                headers: { "set-cookie": "demo_session_token=" + sign(name) + "; HttpOnly" },
                    });
    }