SES-007: add /auth/logout

Техническое задание / Спецификация требований Создать метод /auth/logout для отзыва токена

Author

Системный аналитик

Published

May 28, 2026

NoteКраткая карточка задачи
  • Эпик: Авторизация и аутентификация (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 обязано выполнить следующий алгоритм:

  1. Очистить стейт авторизации: Стереть accessToken из оперативной памяти (Redux/Zustand context).
  2. Очистить хранилище: Принудительно удалить любые локальные токены/куки сессии.
  3. Прервать навигацию: Сбросить стек навигации и перенаправить пользователя на экран авторизации (LoginScreen).
  4. Уведомление: Показать системный алерт или 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.

Сценарий 2: Попытка использования отозванного токена (Защита от Replay Attack)

  • Дано: Токен ранее был отозван через /auth/logout (is_revoked = true).
  • Когда: Отправляется запрос POST /auth/refresh с этим токеном.
  • Тогда:
    • API возвращает 403 Forbidden с JSON-кодом TOKEN_REVOKED_REPLAY_ATTACK.
    • Новая пара токенов доступа не генерируется.