Проблема фрагментации идентификации
В современных корпоративных экосистемах часто встречается ситуация, когда несколько независимых приложений, например набор устаревших сервисов на Laravel, хранят собственные таблицы пользователей, реализуют отдельные механизмы аутентификации и авторизации. На первый взгляд такой подход кажется простым: каждый сервис «сам себе». На практике это приводит к росту операционных рисков. Пользователь, удалённый в одной системе, может оставаться активным в других – явление, известное как access drift. Дублирование записей пользователей, несогласованные роли и отсутствие единого журнала действий делают аудит практически невозможным без ручного, подверженного ошибкам, консолидирования данных.
Архитектурные анти‑паттерны
Разделённое управление идентификацией представляет собой несколько типичных анти‑паттернов:
- Дублирование логики и данных – каждый сервис хранит собственную таблицу
users. Любое изменение (обновление e‑mail, сброс пароля, изменение профиля) требует синхронизации через хрупкие веб‑хуки или ручные скрипты. Это увеличивает объём хранилища и, что важнее, создает нагрузку на разработчиков, которым приходится поддерживать несколько копий одной и той же бизнес‑логики. - Разрозненные правила доступа – роли и разрешения могут различаться в разных приложениях, что приводит к конфликтам и потенциальным уязвимостям. Пользователь, имеющий администраторские привилегии в одном сервисе, может случайно получить ограниченный доступ в другом.
- Отсутствие единого аудита – без централизованного журнала невозможно отследить, где и когда был выполнен тот или иной запрос к системе, что усложняет расследование инцидентов и соблюдение требований регуляторов.
Эти проблемы делают инфраструктуру тяжёлой в обслуживании и подверженной ошибкам безопасности.
Концепция единого источника правды (SSoT)
Для решения перечисленных вопросов необходимо перейти к модели Single Source of Truth (SSoT) – единой точки хранения и управления данными о пользователях. В такой архитектуре все сервисы работают с центральным API‑хабом, который отвечает за:
- хранение единой копии пользовательских записей;
- аутентификацию (например, JWT или OAuth2);
- авторизацию через централизованную модель ролей и прав;
- аудит всех операций (логирование, метрики, события безопасности).
Сервис‑ориентированный подход сохраняет независимость бизнес‑логики приложений, но снимает нагрузку по управлению идентификацией, позволяя сосредоточиться на доменно‑специфических задачах.
Проектирование базы данных
База данных SSoT должна быть построена с учётом масштабируемости и целостности данных. Рекомендуемая схема включает несколько основных таблиц:
| Таблица | Описание |
|---|---|
users | Уникальный идентификатор, e‑mail, хеш пароля, статус (активен/заблокирован), timestamps. |
profiles | Расширенная информация о пользователе (имя, фамилия, телефон, настройки). Связана один‑к‑одному с users. |
roles | Перечень ролей (admin, editor, viewer и т.д.). |
user_roles | Связующая таблица many‑to‑many между users и roles. |
audit_logs | Записи о действиях (логин, изменение пароля, изменение ролей) с указанием времени, IP и источника запроса. |
sessions | Текущие токены/сессии, позволяющие реализовать мгновенный отзыв доступа (revocation). |
Ключевые принципы:
- Уникальность e‑mail – индекс с ограничением
UNIQUEгарантирует отсутствие дублирования. - Нормализация – отдельные таблицы для профилей и ролей упрощают расширяемость.
- Историчность –
audit_logsхранит неизменяемые записи, что облегчает построение отчётов и расследование инцидентов. - Мягкое удаление – вместо физического удаления записей рекомендуется использовать флаг
deleted_at, позволяя восстановить аккаунт при необходимости и сохранять целостность ссылок.
API‑хаб на Next.js
Next.js предоставляет гибкую платформу для реализации API‑хаба благодаря встроенному сервер‑сайд рендерингу и поддержке API Routes. Основные преимущества:
- Единый стек JavaScript/TypeScript – разработчики могут писать как фронтенд, так и бекенд‑логика в одном проекте, что ускоряет доставку фич.
- Мидлвары для безопасности – в
pages/api/_middleware.tsудобно добавить проверку JWT, ограничения по IP и защиту от CSRF. - Автоматическое масштабирование – при размещении на Vercel или других серверлесс‑платформах Next.js автоматически распределяет нагрузки.
- Поддержка Edge Functions – критически важные операции (например, проверка токена) могут выполняться ближе к пользователю, уменьшая латентность.
Типичный набор эндпоинтов:
| Метод | Путь | Описание |
|---|---|---|
POST | /api/auth/login | Аутентификация, выдача JWT и refresh‑токена. |
POST | /api/auth/logout | Инвалидация токена, удаление записи из sessions. |
GET | /api/users/:id | Получение профиля пользователя (с проверкой прав). |
PATCH | /api/users/:id | Обновление данных (e‑mail, пароль, профиль). |
GET | /api/roles | Список доступных ролей. |
POST | /api/users/:id/roles | Назначение ролей пользователю. |
GET | /api/audit | Поиск по журналу аудита (только для админов). |
Для работы с базой данных рекомендуется использовать Prisma – типобезопасный ORM, который генерирует типы из схемы и упрощает миграции. Prisma интегрируется с Next.js без дополнительного конфигурационного накладного кода.
Интеграция с Laravel
Сервис‑ориентированная архитектура подразумевает, что существующие Laravel‑приложения продолжают обслуживать свою бизнес‑логику, но перенаправляют все запросы, связанные с пользователями, к API‑хабу. Интеграция происходит в два шага:
- Клиентская библиотека – в Laravel создаётся сервис‑провайдер, оборачивающий HTTP‑клиент (например, Guzzle) для вызовов Next.js API. Методы
login,fetchUser,assignRolesинкапсулируют детали API. - Middleware аутентификации – вместо стандартного
Auth::attemptиспользуется кастомный middleware, который проверяет JWT, полученный от Next.js, и подгружает пользователя в контекст Laravel черезAuth::onceUsingId.
При такой схеме Laravel получает только «идентификатор» пользователя, а все остальные операции (смена пароля, управление ролями) выполняются в центральном хабе. Это устраняет дублирование кода и гарантирует согласованность данных.
Пути синхронизации и дальнейшее развитие
После внедрения SSoT важным этапом становится поддержка двунаправленной синхронизации для сценариев, когда отдельные сервисы всё же нуждаются в локальном кэше данных. Возможные решения:
- Event‑driven архитектура – каждый сервис публикует события (например,
UserUpdated) в брокер сообщений (Kafka, RabbitMQ). API‑хаб подписывается и актуализирует свою БД. - Webhooks с подписью – хаб отправляет webhook‑уведомления о изменениях, а потребители проверяют подпись HMAC, чтобы гарантировать целостность.
- Periodic reconciliation – плановые задачи сравнивают хеши записей в разных хранилищах и исправляют расхождения.
Дополнительные функции, которые могут быть реализованы в дальнейшем:
- MFA (многофакторная аутентификация) – добавление поддерживаемых провайдеров (TOTP, WebAuthn) в едином сервисе.
- Self‑service portal – пользовательский интерфейс для управления профилем, смены пароля и просмотра активных сессий.
- RBAC с наследованием – более гибкая система ролей, позволяющая группировать разрешения в иерархию.
Переход к централизованному управлению пользователями с использованием Next.js в качестве API‑хаба и Laravel в качестве клиентского слоя позволяет устранить фрагментацию идентификации, снизить операционные риски и упростить масштабирование инфраструктуры. Тщательно спроектированная база данных, строгие политики доступа и автоматизированные механизмы синхронизации делают систему надёжной и готовой к дальнейшему росту компании.