Внедрение RBAC: управление доступом на основе ролей

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

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

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Внедрение RBAC: управление доступом на основе ролей
Средний
~3-5 дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1358
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1250
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    956
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    947

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

Одна из частых ошибок — попытка назначить права каждому пользователю индивидуально. Уже на 50 пользователях это становится ахиллесовой пятой системы: любое изменение требует перебора всех записей. Ролевая модель решает это: вы меняете права одной роли, и все её носители получают обновления. Это сокращает время администрирования на 70% по сравнению с плоской моделью, что для компании со штатом в 100 человек экономит существенную сумму на администрировании ежемесячно. OWASP Access Control Cheat Sheet рекомендует RBAC как стандартный подход для веб-приложений.

Какие проблемы решает RBAC?

Плоское назначение прав, когда права назначаются каждому пользователю отдельно, приводит к неуправляемой матрице при росте штата. RBAC централизует права через роли — изменение роли автоматически применяется ко всем её членам. Отсутствие иерархии заставляет администратора дублировать разрешения для похожих ролей, но иерархический RBAC позволяет задать наследование (например, admin наследует editor). Без RBAC сложно провести аудит прав: нельзя быстро узнать, кто может удалять статьи. RBAC даёт прозрачную матрицу, где достаточно посмотреть разрешения роли.

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

Базовая схема (RBAC0)

Разверните для просмотра схемы

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

CREATE TABLE roles (
    id          SERIAL PRIMARY KEY,
    name        VARCHAR(64) NOT NULL UNIQUE,
    description TEXT
);

CREATE TABLE permissions (
    id       SERIAL PRIMARY KEY,
    resource VARCHAR(128) NOT NULL,
    action   VARCHAR(64)  NOT NULL,
    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)
);

CREATE TABLE role_hierarchy (
    parent_role_id INT REFERENCES roles(id) ON DELETE CASCADE,
    child_role_id  INT REFERENCES roles(id) ON DELETE CASCADE,
    PRIMARY KEY (parent_role_id, child_role_id)
);

Иерархические роли (RBAC1)

Проверка прав с рекурсивным CTE:

WITH RECURSIVE role_tree AS (
    SELECT id FROM roles WHERE id = ?
    UNION ALL
    SELECT rh.parent_role_id
    FROM role_hierarchy rh
    JOIN role_tree rt ON rt.id = rh.child_role_id
)
SELECT DISTINCT p.resource, p.action
FROM role_tree rt
JOIN role_permissions rp ON rp.role_id = rt.id
JOIN permissions p ON p.id = rp.permission_id;
Уровень Описание Пример
RBAC0 Базовая модель: роли и разрешения 3 роли, 20 разрешений
RBAC1 Иерархия ролей: наследование прав admin наследует editor
RBAC2 Ограничения: SSD, DSD Нельзя быть admin и auditor одновременно

Как иерархические роли упрощают поддержку?

В плоской модели при добавлении нового раздела (например, reports) нужно вручную проставить права всем ролям. В иерархической — достаточно дать права верхнеуровневой роли, и все наследники получат их автоматически. Это экономит до 3 часов администрирования в месяц на каждые 10 ролей.

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

Middleware для Express

// 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);

Аналогичный паттерн в Laravel реализуется через Gate и Policy — они также могут использовать кеш.

Почему кеширование прав критично для производительности?

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

// 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}`);
}

Как внедрить RBAC?

  1. Аудит текущей модели доступа. Определите, какие роли уже существуют, как назначаются права, есть ли дублирование.
  2. Проектирование ролей и разрешений. Создайте список ролей (администратор, редактор, пользователь) и разрешений (создание/чтение/обновление/удаление для каждого ресурса).
  3. Реализация схемы базы данных. Создайте таблицы roles, permissions, role_permissions, user_roles. Добавьте индексы для быстрых JOIN.
  4. Написание middleware. Реализуйте проверку прав для каждого запроса. Используйте кеш для снижения нагрузки.
  5. Создание UI администрирования. Разработайте интерфейс для управления ролями и назначения прав.
  6. Интеграция и тестирование. Протестируйте все сценарии: назначение роли, изменение прав, проверку иерархии.

Что входит в реализацию RBAC

  • Аудит текущей модели доступа (если есть)
  • Проектирование схемы RBAC (роли, разрешения, иерархия)
  • Реализация бэкенда (модели, middleware, кеширование)
  • UI для управления ролями (админка)
  • Интеграция с существующей аутентификацией
  • Документация и обучение команды
  • Поддержка 1 месяц после внедрения

Мы внедрили RBAC для 15 проектов за 5 лет работы: от интернет-магазинов до финансовых платформ. Гарантируем прозрачную архитектуру и масштабируемость.

Сроки и экономия

Объём работ Срок
Базовая RBAC0 (без UI) 2–3 дня
С UI администрирования 4–5 дней
С иерархией ролей 6–8 дней
С мультитенантностью 9–12 дней

Экономия на администрировании может быть значительной для компании с 50+ пользователями. Стоимость внедрения окупается в течение 2–3 месяцев. Закажите внедрение RBAC и получите консультацию по вашему проекту. Свяжитесь с нами — оценим объём работ за 1 день.

Аутентификация и авторизация: OAuth, JWT, сессии, RBAC, 2FA

На одном проекте токен JWT с ролью admin: false мог быть изменён клиентом на admin: true — сервер принимал его без верификации подписи. Это не гипотетическая атака: несколько файлов в npm-экосистеме имели уязвимость jwt библиотеки, которая игнорировала алгоритм none. Последствия — полный доступ к административным функциям для любого зарегистрированного пользователя.

JWT: что реально нужно знать

JWT состоит из трёх частей: header (алгоритм), payload (данные), signature (подпись). Подпись верифицирует, что payload не изменён. Без проверки подписи — это просто base64-encoded JSON, который любой может подделать.

Ошибки, которые видим в коде регулярно:

Хранение в localStorage. localStorage доступен любому JS на странице — XSS атака читает токен и отправляет на сервер злоумышленника. Access token в памяти (переменная модуля), refresh token в httpOnly cookie — правильная схема.

Долгоживущие access-токены. Access token на 7 дней без возможности отзыва. Утёк — 7 дней доступа. Стандарт: 15 минут для access token, 30 дней для refresh token с ротацией. При каждом использовании refresh token выдаётся новый, старый инвалидируется — если старый кто-то использует повторно, это детектируется как Token Reuse Attack, вся семья токенов отзывается.

Хранение секретных данных в payload. JWT payload не зашифрован, только подписан — его видно в base64. Пароли, платёжные данные, личная информация — не в JWT.

Алгоритм RS256 (асимметричный) предпочтительнее HS256 (симметричный) в микросервисной архитектуре: сервисы могут верифицировать токен публичным ключом, не имея доступа к секрету для его создания.

OAuth 2.0 и OpenID Connect

OAuth 2.0 — протокол делегированной авторизации, не аутентификации. «Войти через Google» — это OpenID Connect поверх OAuth 2.0, который добавляет id_token с данными пользователя.

Authorization Code Flow с PKCE — единственный правильный flow для браузерных SPA и мобильных приложений. Implicit Flow устарел и небезопасен. PKCE (Proof Key for Code Exchange) защищает от перехвата authorization code.

Реализация OAuth сервера: не пишем с нуля. Keycloak (open source, self-hosted), Auth0, Okta — готовые решения. Laravel Passport или Laravel Sanctum для серверных приложений. NextAuth.js для Next.js — поддерживает 50+ провайдеров из коробки.

Для B2B продуктов с корпоративными клиентами — SAML 2.0 SSO. Корпоративные IT-отделы часто требуют его вместо OAuth. @boxyhq/saml-jackson — node.js библиотека для SAML → OAuth2 адаптера.

Сессии vs токены

Сессии хранят состояние на сервере (Redis, database) — сервер может мгновенно отозвать сессию. При масштабировании на несколько инстансов нужен общий store (Redis Cluster). Cookie с session ID — httpOnly, Secure, SameSite=Strict.

Stateless JWT не требуют server-side storage, масштабируются горизонтально. Но отзыв токена до истечения срока — только через blacklist (Redis), что частично убирает преимущество stateless.

Для большинства веб-приложений сессии проще и безопаснее. JWT имеет смысл для API, потребляемых из мобильного приложения, и для микросервисной архитектуры.

RBAC и политики доступа

Role-Based Access Control — у пользователя есть роли, у ролей — права. Простая реализация: user → roles → permissions. Но как только появляется ресурсная авторизация («пользователь может редактировать только свои посты»), RBAC усложняется.

Spatie Laravel Permission — стандарт для Laravel: полиморфные роли и права, кэширование, super-admin через gate. Интеграция с Eloquent: $user->can('edit posts'), $user->hasRole('editor').

ABAC (Attribute-Based Access Control) — политики на основе атрибутов: пользователя, ресурса, окружения. Нужен когда правила доступа сложные: «менеджер может просматривать заказы своего региона, если заказ создан более 24 часов назад». Casbin — популярная cross-language библиотека для ABAC.

ReBAC (Relationship-Based Access Control) — Google Zanzibar model. Доступ определяется графом отношений: «пользователь X является участником команды Y, которая имеет доступ к проекту Z». OpenFGA — open source реализация от Okta.

Двухфакторная аутентификация

TOTP (Time-based One-Time Password, Google Authenticator, Authy) — стандарт. Библиотеки: otplib (Node.js), pragmarx/google2fa (Laravel). QR-код при подключении — base32-encoded secret, которого достаточно для воспроизведения кода при компрометации. Хранить secret в зашифрованном виде.

SMS-верификация — слабее TOTP из-за SIM-swapping атак и ненадёжности доставки SMS. Но пользователи активируют её охотнее. Email OTP — компромисс между безопасностью и UX.

WebAuthn (Passkeys) — биометрия или аппаратный ключ вместо пароля. Хранится private key на устройстве, публичный — на сервере. Нет пароля — нет его утечки. iOS 16+, Android 9+, все современные браузеры поддерживают. @simplewebauthn/server + @simplewebauthn/browser — хорошая библиотека для Node.js реализации.

Backup-коды при подключении 2FA: 10 одноразовых кодов для восстановления доступа если телефон потерян. Хранить хешированными (bcrypt), показывать только один раз при генерации.

Типичные уязвимости

Broken Object Level Authorization (BOLA/IDOR): /api/orders/12345 возвращает заказ без проверки, принадлежит ли он текущему пользователю. Самая распространённая уязвимость API по OWASP. Каждый запрос к ресурсу — проверка через $user->can('view', $order).

Mass Assignment: User::create($request->all()) — пользователь передаёт is_admin: true в теле запроса. Laravel решает через $fillable / $guarded, но часто забывают.

Небезопасный CORS: Access-Control-Allow-Origin: * на API с авторизацией по cookie — credentials не передаются с wildcard origin, но если кто-то сделал Allow-Credentials: true + Allow-Origin: * — это дыра.

Процесс работы

Архитектура авторизации проектируется до начала разработки, не добавляется потом. Выбор между сессиями и JWT, структура ролей и прав, flow для OAuth-провайдеров, план для 2FA. Penetration testing обязателен для продуктов с финансовыми данными или персональными данными пользователей.

Сроки

Базовая аутентификация (email/password + OAuth + JWT/сессии): 1–3 недели. RBAC с детальными политиками доступа: 2–4 недели. 2FA (TOTP + SMS): 1–2 недели. WebAuthn/Passkeys: 2–3 недели. Полная система аутентификации для SaaS с multi-tenancy: 4–8 недель.