В больших системах требуется гибкая и масштабируемая модель прав. Классическая проверка доступа строится вокруг ролей: пользователь получает одну или несколько ролей (например, admin, manager, viewer), и каждая роль содержит набор разрешений.
Однако при использовании такого подхода появляются проблемы:
- Роли начинают разрастаться и дублировать друг друга.
- Возникают “почти одинаковые” роли с минимальными отличиями.
- Сложно управлять точечными исключениями: если одному пользователю нужно дать доступ только к одной дополнительной кнопке, добавлять новую роль становится избыточно.
Чтобы решить эту задачу и избежать подобных проблем мы используем комбинацию RBAC (Role-Based Access Control) и permission-based подхода ⚙️
У нас есть два уровня:
1 уровень — группы пользователей (можно назвать их ролями: admin, manager, top-manager и т.д).
Это верхнеуровневая агрегация прав. Группа содержит набор доступных для неё permissions.
2 уровень — permissions (разрешение на выполнение действия)
Это атомарные флаги, которые описывают конкретное действие:
- user.edit
- order.create
- order.cancel
- feature.toggleX
Конечный пользователь в итоге получает список доступных permissions через включение его в группы + индивидуальные permissions.
Как это выглядит на frontend
После аутентификации backend возвращает список permissions пользователя. Frontend не работает напрямую с кодами групп/ролей — только с уже “развернутыми” permissions.
const canEdit = usePermission('user.edit');
return <Plate>{canEdit && <EditButton />}</Plate>;Такой подход даёт баланс между управляемостью и гибкостью: роли упрощают администрирование, permissions позволяют точно контролировать поведение интерфейса, а изменение прав пользователей осуществляется без доработок front/back-сервисов ✨
