Ролевая модель для мультисервисной структуры: от проверки по ролям к сетке доступов
В мультисервисном проекте авторизация в каждый сервис ограничивалась по роли пользователя. Количество ролей росло, и стало ясно: проверять нужно не по роли, а по доступам. Мы внедрили гибкую ролевую модель, где пользователь имеет роль и принадлежность к организации, роль — набор доступов по умолчанию, а для каждой организации можно выдать кастомные доступы. Затем создали интерфейс, через который бизнес сам управляет ролями, доступами и видит историю изменений с возможностью отката.
Проблема: роли множились, доступы путались
На проекте, где мы отвечали за авторизацию, сервис рассылок и другие сервисы, так же наши коллеги отвечали за внутренние сервисы на «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. История изменений — обязательна
Ролевая модель — это критичная часть системы. Возможность откатиться до предыдущего состояния — это страховка от ошибок.
Заключение
Эта история — про то, как система переросла свою модель, и как мы не стали латать её бесконечными правками, а перестроили подход: от проверки по ролям к сетке доступов, от ручных изменений к интерфейсу управления.
Гибкая ролевая модель + инструмент управления = система, которая растёт вместе с бизнесом.