Session signée

createSession (de @bext-stack/framework/auth) pose un cookie signé par HMAC ; read() vérifie la signature et l'expiration à chaque requête. Les valeurs altérées échouent à la comparaison en temps constant et la requête est traitée comme anonyme. Le signataire est du HMAC-SHA256 en pur JS — aucune dépendance node:crypto.

Astuce
L'expiration est inscrite dans la charge utile signée, pas seulement dans le Max-Age du cookie — un token copié depuis les DevTools expire quand même côté serveur. Lisez toujours le secret depuis les variables d'environnement plutôt qu'une constante. Ce même module fournit aussi parseCookies, PKCE et la construction d'URL d'autorisation OIDC.

Statut

src/app/examples/session/page.tsxTSX
import { createSession } from "@bext-stack/framework/auth";

// Pure-JS HMAC-SHA256 signer — no node:crypto, runs in any isolate.
const session = createSession<{ name: string }>({
  secret: process.env.SESSION_SECRET!,
  cookie: "sid",
  maxAgeSecs: 600,   // expiry is signed into the payload, not just the cookie
});

export async function loader({ request }) {
  // verifies the signature + expiry; tampered / expired → null
  return { session: session.read(request) };
}

export async function action({ request }) {
  const form = await request.formData();
  if (form.get("op") === "logout")
    return new Response(null, { status: 303, headers: { location: "/", "set-cookie": session.clearCookie() } });
  const name = String(form.get("name"));
  return new Response(null, {
    status: 303,
    headers: { location: "/", "set-cookie": session.cookie({ name, loginAt: Date.now() }) },
  });
}