Реализация RBAC (Role-Based Access Control) для веб-приложения

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация RBAC (Role-Based Access Control) для веб-приложения
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1214
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    852
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    823
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    815

Реализация RBAC (Role-Based Access Control) для веб-приложения

Пользователь заходит в систему и видит ровно то, что ему положено видеть, — не больше и не меньше. Звучит тривиально, пока не начинаешь считать: 12 типов пользователей, 40 разделов интерфейса, матрица разрешений на листе A3, которую нужно поддерживать в коде. RBAC — стандартный ответ на эту задачу: права назначаются не пользователям напрямую, а ролям, пользователи получают роли.

Модель данных

Минимальная схема для PostgreSQL:

CREATE TABLE roles (
    id          SERIAL PRIMARY KEY,
    name        VARCHAR(64) NOT NULL UNIQUE,  -- 'admin', 'editor', 'viewer'
    description TEXT
);

CREATE TABLE permissions (
    id       SERIAL PRIMARY KEY,
    resource VARCHAR(128) NOT NULL,  -- 'articles', 'users', 'reports'
    action   VARCHAR(64)  NOT NULL,  -- 'create', 'read', 'update', 'delete', 'publish'
    UNIQUE (resource, action)
);

CREATE TABLE role_permissions (
    role_id       INT REFERENCES roles(id)       ON DELETE CASCADE,
    permission_id INT REFERENCES permissions(id) ON DELETE CASCADE,
    PRIMARY KEY (role_id, permission_id)
);

CREATE TABLE user_roles (
    user_id INT REFERENCES users(id) ON DELETE CASCADE,
    role_id INT REFERENCES roles(id) ON DELETE CASCADE,
    PRIMARY KEY (user_id, role_id)
);

Это классическая реализация RBAC0. Если нужны иерархические роли (admin наследует все права editor), добавляется таблица role_hierarchy с полями parent_role_id / child_role_id и рекурсивный CTE при проверке.

Проверка прав на бэкенде

Node.js + Express, middleware-подход:

// permissions.js — загружаем права из базы при старте или кешируем в Redis
async function loadUserPermissions(userId) {
  const rows = await db.query(`
    SELECT DISTINCT p.resource, p.action
    FROM user_roles ur
    JOIN role_permissions rp ON rp.role_id = ur.role_id
    JOIN permissions p ON p.id = rp.permission_id
    WHERE ur.user_id = $1
  `, [userId]);

  return new Set(rows.map(r => `${r.resource}:${r.action}`));
}

// middleware/can.js
function can(resource, action) {
  return async (req, res, next) => {
    const perms = await loadUserPermissions(req.user.id);
    if (perms.has(`${resource}:${action}`)) {
      return next();
    }
    res.status(403).json({ error: 'Forbidden' });
  };
}

// routes
router.delete('/articles/:id', authenticate, can('articles', 'delete'), deleteArticle);
router.post('/articles',       authenticate, can('articles', 'create'), createArticle);

Для PHP/Laravel паттерн аналогичен — Gate и Policy:

// AuthServiceProvider
Gate::before(function (User $user, string $ability) {
    if ($user->hasRole('superadmin')) {
        return true; // superadmin обходит все проверки
    }
});

Gate::define('articles.delete', function (User $user) {
    return $user->hasPermission('articles', 'delete');
});

// В контроллере
public function destroy(Article $article)
{
    $this->authorize('articles.delete');
    $article->delete();
    return response()->noContent();
}

Метод hasPermission делает один запрос с JOIN или берёт из кеша — зависит от нагрузки.

Кеширование матрицы прав

На каждый HTTP-запрос гонять JOIN через три таблицы расточительно. Права пользователя меняются редко — это хорошо кешируется:

// redis cache, TTL 5 минут
async function getUserPermissions(userId) {
  const cacheKey = `user_perms:${userId}`;
  const cached = await redis.get(cacheKey);
  if (cached) return new Set(JSON.parse(cached));

  const perms = await loadUserPermissions(userId);
  await redis.setex(cacheKey, 300, JSON.stringify([...perms]));
  return perms;
}

// Инвалидация при изменении ролей пользователя
async function assignRole(userId, roleId) {
  await db.query(
    'INSERT INTO user_roles (user_id, role_id) VALUES ($1, $2) ON CONFLICT DO NOTHING',
    [userId, roleId]
  );
  await redis.del(`user_perms:${userId}`);
}

Управление ролями в интерфейсе

Администратор должен видеть и редактировать матрицу. Минимальный API для этого:

GET    /api/roles                    — список ролей
POST   /api/roles                    — создать роль
GET    /api/roles/:id/permissions    — права роли
PUT    /api/roles/:id/permissions    — обновить права роли (массив permission_id)
GET    /api/users/:id/roles          — роли пользователя
POST   /api/users/:id/roles          — назначить роль
DELETE /api/users/:id/roles/:roleId  — снять роль

На фронте таблица с чекбоксами resource × action — стандартный UI для такого экрана.

Что влияет на сроки

Базовая реализация (3–5 ролей, без наследования, без UI управления ролями) — 2–3 дня. Это схема, middleware, интеграция с существующей аутентификацией, тесты.

Если добавляется UI для управления ролями и правами — ещё 2 дня. Если иерархические роли или мультитенантность (роли изолированы по организации) — закладываем ещё 2–3 дня на усложнение схемы и логики проверок.