Обновить спецификацию auth session-модели для admin API (#23).

Документировать refresh JWT, rotation/reuse и фазы внедрения.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-07 15:30:27 +03:00
committed by Aleksey Sabilin
parent e77fe8ef05
commit 0c1afc6919
3 changed files with 156 additions and 4 deletions
+47 -4
View File
@@ -173,7 +173,8 @@ EventHub — платформа для управления событиями
- Поддержка 100 000+ пользователей.
- Горизонтальное масштабирование добавлением новых узлов.
- Все персистентные таблицы хранятся в `disc_copies` на каждом узле (задача #13).
- Сессионные таблицы (`session`, `admin_session`) оставлены в `ram_copies` для скорости.
- Сессионные таблицы: `auth_session` (единая модель refresh JWT) хранится в `disc_copies` для кластерной устойчивости.
- Legacy-таблицы `session` и `admin_session` (`ram_copies`) сохранены для пользовательского `/v1/refresh` до фазы 2.
- Индексы созданы для часто запрашиваемых полей (calendar_id, start_time, event_type, status и др.) (задача #13).
- Полная репликация горячих таблиц между всеми узлами кластера (задача #14).
- Автоматическое обнаружение узлов через DNS-имя `eventhub-node` или статический список (задача #14).
@@ -263,6 +264,7 @@ src/
- `GET /v1/admin/health` — состояние сервера.
- `GET /v1/admin/stats` — статистика.
- `POST /v1/admin/login` — вход администратора.
- `POST /v1/admin/refresh` — обновление пары access/refresh JWT администратора.
- `GET /v1/admin/users`, `GET /v1/admin/users/:id` — пользователи.
- `GET /v1/admin/reports`, `GET /v1/admin/reports/:id` — жалобы.
- `DELETE /v1/admin/reviews/:id` — удалить отзыв.
@@ -276,9 +278,50 @@ src/
- `GET /v1/admin/audit` — аудит.
## 6.1. Аутентификация и авторизация
- Пользователи и администраторы используют разные эндпоинты и JWT-токены.
- Access-токен имеет срок жизни 1 час, refresh-токен — 30 дней.
- Все защищённые эндпоинты требуют заголовок `Authorization: Bearer <token>`.
### Общие принципы
- Пользователи и администраторы используют разные эндпоинты и JWT-секреты.
- Access-токен — короткоживущий stateless JWT (HS256).
- Refresh-токен — 30 дней; для admin API реализован как подписанный JWT (фаза 1, #23).
- Все защищённые эндпоинты требуют заголовок `Authorization: Bearer <access_token>`.
### Единая session-модель (`auth_session`, фаза 1 — admin)
Таблица Mnesia `auth_session` (`disc_copies`):
| Поле | Описание |
|------|----------|
| `session_id` | Первичный ключ сессии устройства |
| `family_id` | Семейство ротаций одной сессии |
| `subject_id` | ID пользователя или администратора |
| `subject_type` | `user` \| `admin` |
| `client_type` | `admin` \| `web` \| `mobile` |
| `current_jti` | Актуальный jti refresh JWT |
| `expires_at` | Срок жизни сессии (30 дней) |
| `revoked` | Флаг отзыва |
**Refresh JWT (admin)** — claims:
- `typ=refresh`, `aud=admin`, `sub=<admin_id>`
- `sid=<session_id>`, `fid=<family_id>`, `jti=<current_jti>`
- `client=admin`, `exp`, `iat`
**Поток login admin** (`POST /v1/admin/login`):
1. Проверка email/password.
2. Создание записи `auth_session`.
3. Ответ: `{ token, refresh_token, user }`.
**Поток refresh admin** (`POST /v1/admin/refresh`):
1. Верификация подписи и срока refresh JWT.
2. Сверка `jti` из JWT с `current_jti` в Mnesia.
3. При совпадении — ротация: новый `jti`, новая пара токенов.
4. При несовпадении (reuse) — `revoke_family`, ответ 401.
**Фазы внедрения:**
- Фаза 1 (#23): admin API — реализовано.
- Фаза 2: user `/v1/refresh` на той же модели.
- Фаза 3: client web + mobile (тот же контракт `{token, refresh_token}`).
### Legacy user refresh (до фазы 2)
- `POST /v1/login` + `POST /v1/refresh` используют opaque refresh-токен в таблице `session` (`ram_copies`).
## 7. ВЕРСИОНИРОВАНИЕ И СТАТУС
Текущая версия: 1.5 (MVP, альфа). Включает: