Autorisation RBAC
Règles
- Vérifier les permissions sur CHAQUE route avec un middleware — ne jamais rendre l'autorisation optionnelle
- Refuser par défaut : si aucune permission explicite n'est accordée, l'accès est refusé
- Application côté serveur : masquer les éléments d'interface utilisateur n'est PAS de la sécurité, vérifier sur le serveur
- Définir une hiérarchie de rôles : admin > éditeur > lecteur — les rôles supérieurs héritent des permissions inférieures
- Contrôles au niveau des ressources : vérifier
can(user, "edit", ressource) — pas seulement un accès basé sur le rôle
- Auditer toutes les vérifications de permissions — journaliser qui a accédé à quoi et quand, en particulier pour les actions d'administration
- Séparer l'authentification (qui êtes-vous ?) de l'autorisation (que pouvez-vous faire ?)
type Action = "read" | "create" | "update" | "delete";
type Resource = { ownerId: string; [key: string]: any };
function can(user: { id: string; role: string }, action: Action, resource?: Resource): boolean {
const permissions: Record<string, Action[]> = {
admin: ["read", "create", "update", "delete"],
editor: ["read", "create", "update"],
viewer: ["read"],
};
const allowed = permissions[user.role];
if (!allowed?.includes(action)) return false;
if (resource && action !== "read" && user.role !== "admin") {
return resource.ownerId === user.id;
}
return true;
}
function requirePermission(action: Action) {
return (req, res, next) => {
if (!req.user) return res.status(401).json({ error: "Non authentifié" });
if (!can(req.user, action, req.resource)) {
return res.status(403).json({ error: "Interdit" });
}
next();
};
}
app.put("/api/posts/:id", loadResource, requirePermission("update"), updatePost);
À Éviter
- Vérifier les permissions uniquement dans l'interface utilisateur — les attaquants appellent votre API directement
- Autoriser l'accès sauf s'il est explicitement refusé — toujours refuser par défaut
- Utiliser un seul booléen
isAdmin — les rôles doivent être granulaires et extensibles
- Oublier les contrôles au niveau des ressources — "éditeur" ne doit pas signifier "peut modifier le contenu de tout le monde"
- Ignorer l'autorisation sur les points d'accès "internes" — ils deviennent publics à la fin