first commit
This commit is contained in:
97
docs/api-stack/api/api-plugin-auth/src/middleware/session.md
Normal file
97
docs/api-stack/api/api-plugin-auth/src/middleware/session.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# middleware/session
|
||||
|
||||
## Purpose
|
||||
|
||||
`sessionMiddleware` is the global Hono middleware that resolves every
|
||||
incoming request's Better-Auth session and exposes a typed `Principal`
|
||||
through `c.get("user")`. It is installed by `createAuthPlugin`'s
|
||||
`onInit` against `ctx.app` so anonymous routes keep working while
|
||||
protected handlers can rely on `c.get("user")` being either a real
|
||||
`Principal` or `null` — never undefined.
|
||||
|
||||
## Features
|
||||
|
||||
- Calls `auth.api.getSession({ headers: c.req.raw.headers })` once per
|
||||
request and caches the result on the context.
|
||||
- Sets `c.set("user", principal | null)` and `c.set("session", session
|
||||
| null)` via the augmented `ContextVariableMap` (see
|
||||
`./context-augmentation.ts`).
|
||||
- Default mapping uses `mapBetterAuthUserToPrincipal`; opt-out via
|
||||
`principalMapping` for plugin-extended session shapes.
|
||||
- Records `auth.sessions_resolved_total{outcome}` and
|
||||
`auth.session_resolve_duration_ms` for every request, regardless of
|
||||
outcome.
|
||||
- Failures during session resolution set `c.get("user")` to `null`,
|
||||
log at `warn`, and let the request proceed — protected routes still
|
||||
throw `AUTH_UNAUTHENTICATED` via `requireAuth()` so the surface is
|
||||
unaffected.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { sessionMiddleware } from "@suaveplan/api-plugin-auth/middleware/session";
|
||||
import { betterAuth } from "better-auth";
|
||||
|
||||
const auth = betterAuth({ /* … */ });
|
||||
app.use("*", sessionMiddleware({ auth }));
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
Pair the middleware with a custom mapping and a host-supplied logger
|
||||
so role projection and trace correlation are wired in one place:
|
||||
|
||||
```ts
|
||||
import { sessionMiddleware } from "@suaveplan/api-plugin-auth/middleware/session";
|
||||
import { mapBetterAuthUserToPrincipal } from "@suaveplan/api-plugin-auth/principal/principal";
|
||||
|
||||
app.use(
|
||||
"*",
|
||||
sessionMiddleware({
|
||||
auth,
|
||||
logger: ctx.logger,
|
||||
principalMapping: (view) => {
|
||||
const base = mapBetterAuthUserToPrincipal(view);
|
||||
const session = view.session as { roles?: string[] };
|
||||
return { ...base, roles: [...base.roles, ...(session.roles ?? [])] };
|
||||
},
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `function sessionMiddleware(options): MiddlewareHandler`
|
||||
|
||||
`options.auth` is required; `options.principalMapping` and
|
||||
`options.logger` are optional. The returned middleware is async and
|
||||
mutates `c`'s context variables — it never throws.
|
||||
|
||||
### `interface SessionMiddlewareOptions`
|
||||
|
||||
- `auth: Auth` — the Better-Auth instance.
|
||||
- `principalMapping?: PrincipalMapping` — defaults to
|
||||
`mapBetterAuthUserToPrincipal`.
|
||||
- `logger?: LoggerLike` — defaults to a no-op logger.
|
||||
|
||||
### `type PrincipalMapping = (view: BetterAuthSessionView) => Principal`
|
||||
|
||||
### Module augmentation
|
||||
|
||||
`./context-augmentation.ts` declares `interface ContextVariableMap {
|
||||
user: Principal | null; session: BetterAuthSessionResult }` so the
|
||||
typed `c.get("user")` lookups work without a cast in every consumer.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The middleware does NOT throw on failure — anonymous routes must keep
|
||||
working even when Better-Auth's session store is degraded. Protected
|
||||
routes are responsible for raising `AUTH_UNAUTHENTICATED` via
|
||||
`requireAuth()` only when they need an authenticated user.
|
||||
- `performance.now()` is the duration source; the value is recorded in
|
||||
milliseconds (matching the histogram's declared unit).
|
||||
- The outcome label is bounded to `"authenticated"` / `"anonymous"` /
|
||||
`"error"` so dashboards can rely on a fixed cardinality.
|
||||
- Non-`Error` throwables from Better-Auth are normalised via
|
||||
`String(err)` — the middleware does not assume Better-Auth's failure
|
||||
modes are pure `Error` instances.
|
||||
Reference in New Issue
Block a user