Auth Service — Data Model
База данных: auth_db
erDiagram refresh_tokens { uuid id PK uuid user_id string token_hash UK string device_info string ip_address boolean revoked timestamp expires_at timestamp created_at } login_attempts { uuid id PK string email integer attempt_count timestamp locked_until "nullable" timestamp last_attempt_at } password_reset_tokens { uuid id PK uuid user_id string token_hash UK boolean used timestamp expires_at timestamp created_at }
Таблицы
refresh_tokens
Refresh tokens для rotation. При обновлении старый token помечается revoked = true, создаётся новый.
login_attempts
Счётчик неудачных попыток входа. После 5 попыток — блокировка на 15 минут (locked_until). Сбрасывается при успешном входе.
| Поле | Тип | Description |
|---|---|---|
| id | uuid PK | |
| varchar(255) UK | Email сотрудника | |
| attempt_count | integer | Кол-во неудачных попыток (default 0) |
| locked_until | timestamp NULL | Время окончания блокировки |
| last_attempt_at | timestamp | Время последней попытки |
password_reset_tokens
Токены для сброса пароля. TTL = 1 час. Одноразовые (used = true после использования).
| Поле | Тип | Description |
|---|---|---|
| id | uuid PK | |
| user_id | uuid | ID сотрудника |
| token_hash | varchar(255) UK | Хэш токена |
| used | boolean | Использован (default false) |
| expires_at | timestamp | Срок действия (created_at + 1 hour) |
| created_at | timestamp |
Auth Service не хранит пароли
Пароли хранятся в User Service (таблица
employees.password_hash). Auth Service запрашивает валидацию через internal API.
Redis-структуры
| Key pattern | Value | TTL |
|---|---|---|
session:{user_id}:{token_hash} | { user_id, role_ids, franchise_id } (упрощено в BR 1.4.4 — поля role, store_ids удалены) | = access TTL |
user_permissions:{user_id} | JSON: { role_ids: [...], permissions: [...] } (BR 1.4.3) | 60 сек |
user_scope:{user_id} | JSON: { type: "all_franchise" | "legal_entity_ids" | "store_ids", legal_entity_ids?: [...], store_ids?: [...] } (BR 1.4.4) | 60 сек |
Кэш permissions (BR 1.4.3)
user_permissions:{user_id} — агрегированный список permission-ключей сотрудника, полученный из User Service (GET /internal/users/{id}/permissions). Используется POST /internal/auth/validate для отдачи permissions без обращения к User Service на каждый запрос.
Стратегия инвалидации: TTL 60 секунд. Изменения прав роли отражаются на сотруднике через ≤ 60 секунд — компромисс между нагрузкой на User Service и скоростью применения.
Opt-in мгновенная инвалидация (deferred): при необходимости можно добавить эндпоинт DELETE /internal/auth/cache/{user_id}, вызываемый User Service после изменения ролей/прав.
Кэш scope (BR 1.4.4)
(Введено в BR 1.4.4)
user_scope:{user_id} — вычисленный scope сотрудника: либо «вся франшиза», либо список ЮЛ, либо список ТТ. Получается из User Service (GET /internal/users/{id}/scope) при cache-miss. Аналогичная стратегия, что и для permissions: TTL 60 сек. Используется в POST /internal/auth/validate чтобы отдавать scope другим сервисам без отдельного запроса в User Service на каждый вызов.
Scope заменяет ранее использовавшиеся поля JWT store_ids и legal_entity_id — они удалены из payload в BR 1.4.4. Все downstream-сервисы (Store, Catalog, Warehouse, Order) получают scope из ответа validate и используют его для фильтрации данных.