withAuth / withHandler
Wrapper pour les route handlers API Next.js. withAuthlit les headers injectés par authGuard (middleware) et les transmet typés au handler. withHandlerest la version sans authentification, idéale pour les routes publiques (login, logout, webhooks).
Utilisation de base — API protégée
Les route handlers protégés par authGuard reçoivent les headers x-user-*. withAuthles capture et les passe sous forme d’objet AuthInfotypé.
import { withAuth } from "@ramses1er/cbk-toolkit/server";
export const GET = withAuth(async (req, auth) => {
// auth.userId → string
// auth.userRole → string
// auth.permissions → string[]
const user = await findUserById(auth.userId);
return Response.json(user);
});
export const PATCH = withAuth(async (req, auth) => {
const body = await req.json();
await updateUser(auth.userId, body);
return Response.json({ success: true });
});Routes publiques — withHandler
Pour les routes qui ne nécessitent pas d’authentification (login, logout, inscription), utilisez withHandler. Elle fournit le même try/catch que withAuthsans vérifier les headers.
import { withHandler } from "@ramses1er/cbk-toolkit/server";
export const POST = withHandler(async (req) => {
const body = await req.json();
const token = await authenticateUser(body);
return Response.json({ token }, { status: 201 });
});Flux complet — Les 3 couches de protection
Ces trois utilitaires sont conçus pour fonctionner ensemble. Chacun agit à un niveau différent de la requête.
// 1. authGuard — middleware (edge)
// Vérifie le JWT, injecte les headers x-user-*
export async function proxy(request: NextRequest) {
return authGuard(request, {
publicRoutes: ["/", "/api/login", "/api/logout"],
loginUrl: "/",
jwtSecret: process.env.JWT_SECRET!,
});
}
// 2. withAuth — route handler API
// Lit les headers, les passe typés au handler
export const GET = withAuth(async (req, auth) => {
const user = await userRepo.findById(auth.userId);
return Response.json(user);
});
// 3. routeGuard — client React
// Protège l'affichage des pages par rôle
<RouteGuardProvider config={routeGuardConfig}>
{children}
</RouteGuardProvider>Comportement
- Headers présents→ le handler reçoit
(req, auth)avec les infos typées. - Headers manquants →
HttpError401 Non authentifié levé, capturé parhandleServerError. - Toute erreur → catch automatique via
handleServerErrorqui retourne une réponse JSON standardisée. - Route publique →
withHandlerfournit le même try/catch sans vérification d’auth.
API de référence
| Propriété | Type | Défaut | Description |
|---|---|---|---|
withAuth(handler) | |||
| handler | (req: Request, auth: AuthInfo) => Promise<Response> | requis | Handler avec authentification |
withHandler(handler) | |||
| handler | (req: Request) => Promise<Response> | requis | Handler sans authentification |
AuthInfo | |||
| userId | string | — | ID de l’utilisateur (header x-user-id) |
| userRole | string | — | Rôle de l’utilisateur (header x-user-role) |
| permissions | string[] | [] | Permissions (header x-user-permissions, CSV) |
Types TypeScript
export interface AuthInfo {
userId: string;
userRole: string;
permissions: string[];
}
// withAuth : wrapper protégé
export function withAuth(
handler: (req: Request, auth: AuthInfo) => Promise<Response>,
): (req: Request) => Promise<Response>
// withHandler : wrapper sans auth
export function withHandler(
handler: (req: Request) => Promise<Response>,
): (req: Request) => Promise<Response>