ACL и RBAC на фронтенде

↑ 5.5 Аутентификация и доступ: Keycloak, SSO, ACL · ← Предыдущая

Обязательно~3 мин чтенияУровень: middle

Зачем это на собесе

Как отображать интерфейс по правам, помня, что настоящая защита на сервере.

Объяснение

МодельСуть
RBAC (role-based)права привязаны к ролям (admin, manager), пользователь получает роли
ACL (access control list)список прав на конкретный объект («пользователь X может редактировать документ Y»)
ABAC (attribute-based)политика по атрибутам (отдел, время, владение, статус объекта)
Permissions (права)атомарные действия orders:read, orders:write — роли группируют права

Клиентская сторона — отображение: маршруты, меню, кнопки, поля.

// stores/permissions.ts
export const usePermissions = defineStore("permissions", () => {
  const perms = ref(new Set<string>());
  const can = (p: string) => perms.value.has(p) || perms.value.has("*");
  const canAny = (...ps: string[]) => ps.some(can);
  return { perms, can, canAny };
});
 
// Директива
app.directive("can", { mounted(el, { value }) { if (!usePermissions().can(value)) el.remove(); } });
// <q-btn v-can="'orders:write'" label="Создать" />
 
// Компонент
// <Can permission="orders:delete" :resource="order"><q-btn label="Удалить" /></Can>
 
// Маршруты и меню
router.beforeEach((to) => { const need = to.meta.permissions; if (need && !usePermissions().canAny(...need)) return { name: "forbidden" }; });
const menu = computed(() => allMenu.filter(i => !i.permission || can(i.permission)));

Практики:

  • Источник прав — бэкенд (endpoint /me/permissions или claims токена); фронтенд не выводит права из «названий ролей» по своей логике.
  • Права на уровне объектов (владелец, статус) приходят с данными (order.permissions: { canEdit, canDelete }) — фронтенд не дублирует бизнес-правила.
  • Отображение: скрывать или блокировать? Скрывайте недоступные разделы, блокируйте с подсказкой действия, которые «временно недоступны».
  • Реактивность: при смене пользователя/прав пересчитывайте меню и очищайте кэш.
  • 403 от API обрабатывается: показать сообщение и обновить права.
  • Тестирование матрицы «роль × экран/действие».

Проверка на сервере обязательна для каждого запроса; клиентское скрытие — только UX.

Нюансы и подводные камни

  • Хардкод ролей в компонентах (v-if="user.role === 'admin'") размазывает правила: используйте права.
  • Утечка информации: клиентский бандл содержит все страницы (даже скрытые) — не помещайте секреты.
  • Рассинхронизация прав фронта и бэка — источник багов «кнопка есть, а 403».
  • Права из старого токена не обновляются до refresh.

Практика

  1. Реализуйте usePermissions, директиву v-can и фильтрацию меню.
  2. Получайте права объекта с сервера и отображайте кнопки по ним.
  3. Составьте матрицу ролей и проверьте её тестами.

Вопросы с ответами

Связанные темы