Аутентификация

API использует короткоживущий access JWT поверх управляемого серверного сеанса устройства. Access-токен подтверждает запрос, а ротируемый refresh-механизм продлевает сеанс и позволяет немедленно отозвать доступ.

Создание управляемого сеанса

POST /auth/login проверяет пароль, регистрирует установку и создаёт серверный сеанс. Клиент передаёт стабильный installation_id и безопасные отображаемые сведения об устройстве. Для учеников школа может ограничить количество одновременно активных устройств.

Содержимое токена (payload)
{
  "user_id": "8f3b1c2a-...",
  "tenant_id": "1b9d6bcd-...",
  "role": "admin",
  "sid": "745810eb-...",
  "jti": "8cce7f8a-...",
  "exp": 1749600000
}
sid связывает access JWT с серверным сеансом. Поэтому выход, блокировка устройства, смена пароля или действие администратора прекращают доступ до естественного истечения access-токена.

Передача токена

Добавляйте токен в заголовок Authorization со схемой Bearer:

Заголовок
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Для запросов к данным школы (/api/v1/t/*) дополнительно нужен заголовок X-Tenant-Subdomain — см. Мультитенантность.

Продление сеанса

  • Access JWT живёт недолго и хранится браузером только в памяти.
  • В браузере refresh-секрет находится в tenant+device-scoped HttpOnly Secure cookie: JavaScript не может его прочитать или скопировать в localStorage. Клиент хранит только non-secret session_id и auth_device_id, чтобы сервер выбрал точную cookie.
  • Нативное приложение получает refresh_token в JSON, хранит его в защищённом хранилище и после каждого refresh атомарно заменяет новым значением.
  • При 401 клиент выполняет ровно один общий POST /auth/refresh, обновляет access JWT и один раз повторяет ожидавшие запросы. Циклический refresh запрещён.
Ротация и параллельные запросы
Refresh-токен одноразовый. Клиент должен объединять конкурентные попытки продления. Краткая серверная grace-обработка отличает обычную гонку вкладок от подтверждённого повторного использования старого токена.

Лимит и замена устройства

Если школа включила режим ограничения и свободных мест нет, login отвечает 409 device_limit_reached. Ответ содержит только безопасные сведения об активных устройствах и краткоживущий replacement_token. При разрешённой самостоятельной замене клиент вызывает POST /auth/device-limit/replace; пароль повторно в запрос замены не передаётся и не сохраняется.

Завершение и отзыв

  • POST /auth/logout с session_id и auth_device_id отзывает текущий серверный сеанс и очищает только его browser cookie.
  • Ученик может просмотреть свои устройства и выйти на остальных, если школа разрешила самоуправление.
  • Администратор может завершить сеансы, заблокировать конкретную установку или отозвать все сеансы ученика.
  • Политика школы может автоматически отзывать сеансы после смены или восстановления пароля.

Проверка текущего пользователя

Эндпоинт GET /auth/me возвращает профиль владельца токена и состояние биллинга школы. Используйте его, чтобы проверить валидность токена и получить роль.

cURL
curl https://api.edumentor.kz/api/v1/auth/me \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme"
Защита от перебора
Слишком частые неудачные попытки входа блокируются — POST /auth/login ответит 423 с сообщением too many attempts, try again later. Сообщение обобщённое и не раскрывает, существует ли аккаунт.

Переход со старых JWT

Сервер поддерживает ограниченный переходный режим для старых tenant JWT без sid: allow временно разрешает выпуск и приём, existing_only принимает только уже выданные до их exp, а deny полностью требует управляемые сеансы. Tenantless-токены суперадмина мигрируют отдельно. Новые клиенты не должны полагаться на legacy-режим.