Ролевая модель для мультисервисной структуры: от проверки по ролям к сетке доступов

В мультисервисном проекте авторизация в каждый сервис ограничивалась по роли пользователя. Количество ролей росло, и стало ясно: проверять нужно не по роли, а по доступам. Мы внедрили гибкую ролевую модель, где пользователь имеет роль и принадлежность к организации, роль — набор доступов по умолчанию, а для каждой организации можно выдать кастомные доступы. Затем создали интерфейс, через который бизнес сам управляет ролями, доступами и видит историю изменений с возможностью отката.

Ролевая модель для мультисервисной структуры: от проверки по ролям к сетке доступов

Проблема: роли множились, доступы путались

На проекте, где мы отвечали за авторизацию, сервис рассылок и другие сервисы, так же наши коллеги отвечали за внутренние сервисы на «1С-Битрикс», доступ в каждый сервис ограничивался по роли пользователя.

Как это выглядело:

  • Роли «Администратор» видели свои сервисы после авторизации.

  • Клиенты — свои публичные сервисы.

  • Поддержка — свои.

Поначалу это работало. Но количество ролей росло. Появлялись новые сервисы, новые сценарии, новые типы пользователей. И с каждой новой ролью приходилось заново описывать, что ей доступно, а что нет.

Проверка «по роли» стала узким местом. Мы решили внедрить сетку доступов: проверять не по роли, а по доступам, которые к ней привязаны.


Первая итерация: роль + организация + доступы

Мы спроектировали модель, в которой:

  • Пользователь имеет роль и принадлежность к организации.

  • Роль имеет набор доступов по умолчанию — это доступы к сервисам, возможности авторизации (двухфакторная, однофакторная, SMS, только по номеру телефона и коду, смешанные), доступ к функциональным блокам.

  • Для каждой организации и роли можно выдать кастомные доступы.

Что это дало:

Один пользователь с ролью «Менеджер» в организации А мог иметь один набор доступов. Другой пользователь с той же ролью в организации Б — другой набор. Третий — в организации В — третий.

Роль перестала быть жёсткой рамкой. Она стала шаблоном, который можно настраивать под конкретную организацию.


Как это работало: полный цикл авторизации

Опишем путь пользователя от формы входа до попадания в сервис.

1. Выбор способа авторизации

На форме авторизации пользователь выбирает: email + пароль или номер телефона + SMS.

2. Заполнение формы

Пользователь вводит данные по выбранному типу авторизации.

3. Проверка на бэкенде

Уходит запрос на бэкенд. Система проверяет наличие пользователя — либо по номеру телефона, либо по email, в зависимости от введённых данных.

4. Если пользователь не найден

Выводится сообщение: «Пользователя с такими данными не существует. Проверьте данные или пройдите регистрацию».

5. Если пользователь найден

Проверяем, какие способы авторизации доступны для его роли. Если выбранный способ не подходит — выводится сообщение с предложением авторизоваться доступным способом. Затем идёт набор шагов согласно его ролевой модели.

6. Меню выбора сервисов

После авторизации пользователь попадает на меню выбора сервисов.

  • Если его роль принадлежит к внутренним сотрудникам, ему доступны две категории сервисов: для внутренних пользователей и для внешних. Иначе доступны только сервисы для внешних пользователей.

  • Сервисы выводятся исходя из доступов роли. Сервисы, к которым доступа нет, не отображаются.

7. Авторизация в сервис через OAuth 2.0

При нажатии на сервис мы авторизуем пользователя в него посредством OAuth 2.0. После «рукопожатия» систем конечная система делает запрос по актуальным доступам пользователя — и наша система по API выдаёт набор доступов в формате JSON. При завершении авторизации конечный сервис запоминает набор доступов в сессии пользователя.

8. Пользователь в сервисе

В итоге пользователь имеет на каждом сервисе набор доступов, согласно которому может пользоваться сервисом.

9. API-пользователи

API-пользователи также имеют свои доступы — по той же модели.


Рост системы: ролевая модель стала тесной

Когда система начала расти, мы были вынуждены расширять и саму ролевую модель.

Как это происходило:

  • На первых этапах ролевая модель была конечной — набор ролей и доступов был фиксирован.

  • Затем бизнес регулярно начал добавлять через разработку новые роли и доступы.

  • Появились запросы на изменение набора доступов для конкретной организации, к которой относится роль.

Каждое такое изменение — это задача для разработки. Бизнес ждал, команда тратила время на рутинные правки.


Решение: интерфейс управления ролевой моделью

Мы предложили бизнесу дать интерфейс работы с ролевой моделью. Нам дали согласие.

Мы создали интерфейс в приложении управления пользователями и системами (стек — Laravel + Vue.js).

Что можно было делать в интерфейсе:

  • Добавить группу ролей и роль.

  • У каждой роли — латинское наименование и наименование на кириллице.

  • Указать, внутренняя это роль или внешняя.

  • Создать группу доступов и доступы.

  • У каждого доступа — латинское и кириллическое наименование.

  • Латинское наименование использовалось системами для указания разрешений для доступов.

История изменений и откат

Мы внедрили функционал истории изменения ролевой модели. Можно было «откатиться» до любого предыдущего состояния — если что-то пошло не так или нужно вернуть прежнюю конфигурацию.

Основной раздел: сетка доступов

Ключевой элемент интерфейса — сетка доступов, сервисов и ролей, где нужно было проставить: разрешён или запрещён доступ. В редактировании каждой организации была такая же сетка дабы можно было управлять её ролями и доступами для них.

Это дало бизнесу самостоятельность: они могли менять ролевую модель без участия разработчиков.


Результат: гибкая модель + инструмент управления

Мы не просто разработали гибкую ролевую модель под нужды бизнеса — мы создали интерфейс для управления этой моделью.


Стек

  • Backend: Laravel (PHP)

  • Frontend: Vue.js

  • Авторизация: OAuth 2.0

  • Обмен данными: API, JSON


Что мы вынесли из этой истории

1. Проверка по ролям не масштабируется

Когда ролей становится много, проверка «по роли» превращается в хаос. Проверка по доступам — более гибкий и предсказуемый подход.

2. Контекст важен: одна роль — разные доступы

Пользователь с одной и той же ролью в разных организациях может иметь разные доступы. Это реальность B2B — и модель должна это учитывать.

3. Бизнесу нужен инструмент, а не очередь к разработчикам

Если бизнес регулярно просит изменить роли и доступы — дайте ему интерфейс. Это освобождает команду и ускоряет бизнес.

4. История изменений — обязательна

Ролевая модель — это критичная часть системы. Возможность откатиться до предыдущего состояния — это страховка от ошибок.


Заключение

Эта история — про то, как система переросла свою модель, и как мы не стали латать её бесконечными правками, а перестроили подход: от проверки по ролям к сетке доступов, от ручных изменений к интерфейсу управления.

Гибкая ролевая модель + инструмент управления = система, которая растёт вместе с бизнесом.

Обсудим проект

Расскажите о задаче — оценим за пару дней

Контакты