Autorização RBAC
Regras
- Verifique permissões em CADA rota com middleware — nunca torne a autorização opcional
- Negue por padrão: se nenhuma permissão explícita for concedida, o acesso é negado
- Aplicação no servidor: esconder elementos da UI NÃO é segurança — verifique no servidor
- Defina hierarquia de papéis: admin > editor > viewer — papéis superiores herdam permissões inferiores
- Verificações em nível de recurso: verifique
can(user, "edit", resource) — não apenas acesso baseado em papel
- Audite todas as verificações de permissão — registre quem acessou o quê e quando, especialmente para ações de administrador
- Separe autenticação (quem é você?) de autorização (o que você pode fazer?)
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: "Não autenticado" });
if (!can(req.user, action, req.resource)) {
return res.status(403).json({ error: "Proibido" });
}
next();
};
}
app.put("/api/posts/:id", loadResource, requirePermission("update"), updatePost);
Evite
- Verificar permissões apenas na UI — invasores chamam sua API diretamente
- Permitir acesso a menos que explicitamente negado — sempre negue por padrão
- Usar um único booleano
isAdmin — os papéis devem ser granulares e extensíveis
- Esquecer verificações em nível de recurso — "editor" não deve significar "pode editar o conteúdo de todos"
- Pular autorização em endpoints "internos" — eles se tornam públicos eventualmente