Express
Mount Radon as Express middleware — one router for all auth routes, plus requireAuth and withAuth guards for your own routes.
Radon plugs into Express as ordinary middleware: mount radonExpress(auth) under
a base path, and guard your own routes with requireAuth.
Body parsing is required
Radon reads req.body on POST routes, so express.json() must run before the
auth middleware.
1. Mount the auth routes
import express from "express";
import { radonExpress } from "@radonsdk/auth/integrations/express";
import { auth } from "./auth";
const app = express();
app.use(express.json());
// Serves every auth route under /api/auth.
app.use("/api/auth", radonExpress(auth));
app.listen(3000, () => console.log("http://localhost:3000"));2. Guard your own routes
requireAuth blocks unauthenticated requests with 401 and, on success,
attaches the user to req.radonUser (and req.radonUserId).
import { radonExpress, requireAuth } from "@radonsdk/auth/integrations/express";
app.get("/me", requireAuth(auth), (req, res) => {
res.json(req.radonUser); // guaranteed present here
});Optional auth
withAuth never blocks — it attaches req.radonUser if there's a valid
session, and leaves it undefined otherwise. Good for pages that render
differently when logged in.
import { withAuth } from "@radonsdk/auth/integrations/express";
app.get("/", withAuth(auth), (req, res) => {
res.send(req.radonUser ? `Hi ${req.radonUser.email}` : "Hello, guest");
});Options
app.use("/api/auth", radonExpress(auth, {
cookieName: "acme_session",
successRedirect: "/dashboard",
failureRedirect: "/signin?error=1",
}));TypeScript: typing req.radonUser
req.radonUser is attached at runtime. To type it, augment Express's Request
in a .d.ts: declare global { namespace Express { interface Request { radonUser?: RadonUser; radonUserId?: string } } }.
CSRF
For your own state-changing routes:
import { issueCsrfToken, verifyCsrfToken } from "@radonsdk/auth/integrations/express";