@authdog/express
v0.3.1
Published
Authdog Express SDK
Readme
@authdog/express
Authdog SDK for Express — session middleware, an
authentication gate, and a logout handler for Node.js backends. Built on
@authdog/node-commons, so public-key parsing, cookie
handling, and the trusted identity-host allowlist are shared with the rest of
the Authdog Web SDK.
Install
bun add @authdog/express expressexpress is a peer dependency (Express 4 or 5).
Quick start
import express from "express";
import { createAuthdog } from "@authdog/express";
const app = express();
const authdog = createAuthdog({
publicKey: process.env.PK_AUTHDOG!, // pk_… (safe to expose to the browser)
});
// Resolve the session for every request and attach `req.authdog`.
app.use(authdog.attachSession());
// Public route — `req.authdog` is always present after `attachSession`.
app.get("/", (req, res) => {
res.json({ authenticated: req.authdog?.isAuthenticated ?? false });
});
// Protected route — `requireAuth` is the real server-side enforcement point.
app.get("/me", authdog.requireAuth, (req, res) => {
res.json(req.authdog!.user);
});
// Clears the session cookie and redirects to a sanitized `redirect_uri`.
app.get("/logout", authdog.logout);
app.listen(3000);How it works
attachSession(options?)— reads the session token from theauthdog-sessioncookie or anAuthorization: Bearer <token>header. When a token is present it calls the identity provider'suserinfoendpoint and attaches the result toreq.authdog:interface AuthdogRequestContext { token: string | null; user: unknown | null; isAuthenticated: boolean; userInfo?: UserInfoResponse | null; }It never throws and never blocks the request — a missing, invalid, or unverifiable token simply yields
isAuthenticated: false. Mount it once, early, so every downstream handler can readreq.authdog.requireAuth— responds401 { "error": "Unauthorized" }whenreq.authdog?.isAuthenticatedis falsy, otherwise callsnext(). This is the security boundary. Client-side checks are presentational only; every protected route must sit behindrequireAuth.logout— expires theauthdog-sessioncookie (HttpOnly,SameSite=Lax,Securein production) and redirects to theredirect_uriquery parameter after running it throughsanitizeRedirectPathto prevent open redirects.
Options
attachSession({ fetchUser })
By default attachSession performs one outbound HTTPS request per incoming
request that carries a token to resolve the full user object. For
high-throughput services that only need to know whether a token is present (and
validate it elsewhere), opt out:
app.use(authdog.attachSession({ fetchUser: false }));With fetchUser: false, req.authdog.token is populated but
isAuthenticated stays false and user stays null — you are responsible
for validating the token where it matters.
Security
- The public key is validated and parsed once at startup; a malformed or untrusted key (one whose identity host is not on the allowlist) throws immediately rather than per-request.
- The bearer token is only ever sent to a trusted,
https:identity host — enforced by@authdog/node-commons. - A request is treated as authenticated only when the
userinfoenvelope reports success (meta.code === 200with auser).
License
MIT
