RouteGuard Provider + auto-protection
Protection de routes côté client basée sur les rôles. Le Provider détecte automatiquement le chemin de chaque page et vérifie le roleName courant. Vous fournissez un hook qui retourne une simple chaine, le toolkit compare avec pagePermissions. Complète la protection côté serveur : Option A authGuard (JWT) ou Option B proxy better-auth (voir page SessionExpired).
Dans le dossier src/config/de votre projet, créez un fichier permissions.ts. C’est ici que vous définissez qui peut accéder à quoi. Les deux options sont valides, choisissez selon votre auth.
Option A — JWT / session classique
Mappez votre réponse /api/me vers une simple chaine. Votre hook, nom libre, doit retourner roleName + isLoading.
import { createRouteGuardConfig } from "@ramses1er/cbk-toolkit/client";
// Votre hook, nom libre. Doit retourner roleName + isLoading.
// Mappez votre reponse /api/me vers une simple chaine.
export function useRoleName() {
const { data, isLoading } = fetchCurrentUser();
return { roleName: data?.roleName ?? null, isLoading };
}
export const routeGuardConfig = createRouteGuardConfig({
useRoleName,
pagePermissions: {
"/administrations": ["admin"],
"/dashboard": ["admin", "manager"],
"/profile": ["admin", "manager", "user"],
},
deniedPath: "/access-denied",
});Option B — better-auth (authClient.useSession)
Si vous utilisez better-auth, utilisez authClient.useSession() dans src/config/permissions.ts. Seul le contenu de useRoleNamechange :pagePermissions et deniedPathrestent identiques. Adaptez ensuite les rôles à vos routes.
"use client";
import { createRouteGuardConfig } from "@ramses1er/cbk-toolkit/client";
import { authClient } from "@/lib/auth-client";
export function useRoleName() {
const { data, isPending } = authClient.useSession();
return { roleName: data?.user ? "admin" : null, isLoading: isPending };
}
export const routeGuardConfig = createRouteGuardConfig({
useRoleName,
pagePermissions: {
"/administrations": ["admin"],
"/dashboard": ["admin", "manager"],
"/profile": ["admin", "manager", "user"],
},
deniedPath: "/access-denied",
});pagePermissions peut devenir { "/dashboard": ["admin"], "/enrollment": ["admin", "student"] } selon vos routes. Seule la logique interne de useRoleNamedépend de better-auth.Paramètres :
useRoleName— votre hook React qui retourne{ roleName, isLoading }avec roleName string ou nullpagePermissions— objet qui associe chaque chemin aux rôles autorisésdeniedPath— (optionnel) page de redirection si accès refusé. Défaut :/access-denied
Dans src/app/layout.tsx, importez la config et enveloppez l’application avec RouteGuardProvider.
import { RouteGuardProvider } from "@ramses1er/cbk-toolkit/client";
import { routeGuardConfig } from "@/config/permissions";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<RouteGuardProvider config={routeGuardConfig}>
{children}
</RouteGuardProvider>
);
}Les permissions sont héritées par les sous-chemins. Une seule règle suffit pour protéger tout un module.
| Route | Rôles autorisés | Défini dans la config |
|---|---|---|
| /administrations | admin | oui |
| /administrations/users | admin | hérité de /administrations |
| /administrations/users/ajouter | admin | hérité de /administrations |
| /dashboard | admin, manager | oui |
| /profile | admin, manager, user | oui |
| /public | aucune restriction | non défini |
- Pas de permissions configuréespour le chemin → la page est accessible sans vérification
- Chargement→ écran de chargement pendant la récupération de l’utilisateur
- Utilisateur non connecté ou rôle non autorisé → redirection vers
deniedPath - Rôle autorisé→ la page s’affiche normalement
- Héritage→ une permission sur
/adminprotège aussi/admin/users,/admin/settings, etc.
createRouteGuardConfig→ vous définissez les droits par route<RouteGuardProvider config={routeGuardConfig}>