SES-007: add /auth/logout
Техническое задание / Спецификация требований Создать метод /auth/logout для отзыва токена
- Эпик: Авторизация и аутентификация (EPIC-10)
- Компонент: NGINX, R Gatekeeper (Backend API), Postgres (Auth DB), Mobile App (AgroLaborApp)
- Статус: Готово к реализации
- Ссылка на Jira: SES-007
1. Бизнес-контекст и цель (Business Context)
В рамках повышения информационной безопасности платформы “Цифровые симуляторы бизнес-процессов” необходимо обеспечить гарантированное завершение пользовательской сессии при выходе из системы. Ранее токены обновления могли оставаться валидными до истечения их TTL, что создавало риски безопасности.
Цель задачи: Реализовать эндпоинт /auth/logout, который принудительно отзывает токен обновления (refresh_token) в базе данных при выходе пользователя из мобильного приложения или веб-сайта. Это исключает возможность повторного использования (Replay Attack) токена злоумышленником в случае его компрометации после закрытия сессии.
2. Пользовательские истории (User Stories)
Как Авторизованный пользователь приложения AgroLaborApp,
Я хочу иметь возможность безопасно выйти из своей учетной записи по нажатию кнопки «Выход»,
Чтобы никто другой не смог получить доступ к мои данным или обновить сессию с моего устройства.
3. Системные требования и бизнес-логика (Functional Requirements)
3.1. Модель данных (Data Model Updates)
Работа с сессиями и токенами обновления ведется в существующей таблице refresh_tokens в Postgres (Auth DB). При реализации логики логаута и валидации необходимо использовать следующие поля:
| Поле | Тип | Описание | Бизнес-логика задачи |
|---|---|---|---|
id |
integer |
Primary Key | Автоинкрементный идентификатор записи. |
user_id |
integer |
Foreign Key | Идентификатор пользователя, совершившего выход. |
token_hash |
text |
Index | Хэш токена обновления. Используется для поиска записи при POST /auth/logout и POST /auth/refresh. |
expires_at |
timestamp |
Date/Time | Срок действия токена. Если текущее время больше expires_at, токен недействителен. |
is_revoked |
boolean |
Flag | Флаг отзыва токена. По умолчанию false. При вызове /auth/logout переводится в true. |
3.2. Алгоритм и SQL-запросы для разработчиков (Backend Logic)
Шаг 1. Метод /auth/logout (Этап 2 схемы)
При получении запроса на выход, сервис R Gatekeeper должен перевести флаг is_revoked в состояние true для текущего токена:
UPDATE refresh_tokens
SET is_revoked = true
WHERE token_hash = $1;Шаг 2. Метод /auth/refresh (Этап 3 схемы — Проверка Replay Attack)
При попытке обновить сессию бэкенд проверяет валидность записи:
SELECT id, user_id, is_revoked, expires_at
FROM refresh_tokens
WHERE token_hash = $1;4. Спецификация API (API Specification)
4.1. POST /auth/logout
Вызывается принудительно при выходе пользователя из системы.
Пример запроса:
POST /auth/logout HTTP/1.1
Host: ://yourcompany.com
Cookie: refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Пример успешного ответа (Response 200 OK):
{
"success": true,
"message": "Сессия успешно завершена. Токен отозван."
}4.2. Обработка ошибки валидации токена (Response 403 Forbidden)
Вызывается методом POST /auth/refresh в сценарии Replay Attack (когда токен найден в БД, но поле is_revoked == true).
{
"success": false,
"error": {
"code": "TOKEN_REVOKED_REPLAY_ATTACK",
"message": "The provided refresh token has been revoked. Security alert raised.",
"details": {
"reason": "Session was previously terminated via logout",
"action_required": "FORCE_LOCAL_LOGOUT"
}
},
"timestamp": "2026-05-28T00:48:00Z"
}4.3. Требования к фронтенду / мобильному клиенту (React Native App)
При перехвате ответа с кодом TOKEN_REVOKED_REPLAY_ATTACK мобильное приложение AgroLaborApp обязано выполнить следующий алгоритм:
- Очистить стейт авторизации: Стереть
accessTokenиз оперативной памяти (Redux/Zustand context). - Очистить хранилище: Принудительно удалить любые локальные токены/куки сессии.
- Прервать навигацию: Сбросить стек навигации и перенаправить пользователя на экран авторизации (
LoginScreen). - Уведомление: Показать системный алерт или Toast-уведомление на языке интерфейса:
- RU: “Ваша сессия была завершена на другом устройстве или истекла. Пожалуйста, войдите в систему заново.”
- EN: “Your session was terminated on another device or has expired. Please log in again.”
5. Критерии приемки и тест-кейсы (Acceptance Criteria)
Сценарий 1: Успешный выход из системы (Счастливый путь)
- Дано: Пользователь авторизован в AgroLaborApp. В БД Postgres строка токена имеет
is_revoked = false. - Когда: Пользователь нажимает «Выход», и отправляется запрос
POST /auth/logout. - Тогда:
- API возвращает
200 OK. - В БД значение
is_revokedдля данного токена изменилось наtrue.
- API возвращает
Сценарий 2: Попытка использования отозванного токена (Защита от Replay Attack)
- Дано: Токен ранее был отозван через
/auth/logout(is_revoked = true). - Когда: Отправляется запрос
POST /auth/refreshс этим токеном. - Тогда:
- API возвращает
403 Forbiddenс JSON-кодомTOKEN_REVOKED_REPLAY_ATTACK. - Новая пара токенов доступа не генерируется.
- API возвращает