sequenceDiagram
autonumber
actor App as APP (Мобильное приложение)
participant Nginx as Nginx Proxy
participant GW as GATEWAY (backend-api)
participant Auth as AUTH (auth-service)
participant Redis as REDIS (Token Blacklist)
participant DB as DB_AUTH (PostgreSQL)
App->>Nginx: Шаг 1: POST /api/v1/auth/logout (Bearer Access / Body Refresh)
activate Nginx
Nginx->>GW: Шаг 2: POST /backend-api/v1/auth/logout
activate GW
GW->>Auth: Шаг 3: gRPC: LogoutUser(LogoutRequest)
activate Auth
Auth->>Redis: Шаг 4: Redis.SET(blacklist:access, ex=TTL)
activate Redis
note over Auth, Redis: При падении Redis:<br/>Fail-Close -> Аварийный выход HTTP 503
Redis-->>Auth: Токен успешно заблокирован в кэше
deactivate Redis
Auth->>DB: Шаг 5: SQL UPDATE user_sessions SET is_revoked = true...
activate DB
DB-->>Auth: Статус сессии обновлен в БД
deactivate DB
Auth-->>GW: Шаг 6: gRPC: LogoutResponse
deactivate Auth
GW-->>App: Шаг 7: HTTP 200 OK (status: success)
deactivate GW
deactivate Nginx
note over App: Шаг 8: Внутренний метод<br/>SecureStorage.deleteAll() и редирект
Метод POST /api/v1/auth/logout
Документация API: Деактивация сессии пользователя (Logout) с каскадной инвалидацией WebSocket-дескрипторов
- GW-104 Ready for Development — Подключение эндпоинта в шлюзе.
- IAD-015 Ready for Development — создать метод LogoutUser(LogoutRequest).
- INV-FRONTEND-2XX Refinement (Уточнение) — Экран управления B2B-интеграциями
В открытом доступе представлена демонстрационная версия метода. В настоящей публичной документации отображены не все шаги, технические сценарии и приватные эндпоинты для системы цифровых симуляторов бизнес-процессов.
- Полная спецификация метода: Будет доступна только во внутреннем контуре разработки (Confluence / Swagger Enterprise).
1 Функциональное назначение
Метод предназначен для корректного и безопасного завершения текущей пользовательской сессии в экосистеме .
В рамках новой распределенной архитектуры метод POST /logout решает три ключевые задачи:
- Аннулирование долгоживущей сессии (Revocation): Переводит флаг
is_revokedцелевогоrefresh_tokenв состояниеtrueв таблицеuser_sessions, полностью блокируя возможность фонового продления сессии черезDio Interceptor. - Очистка ресурсов WebSocket-менеджера: Отправляет внутренний асинхронный сигнал в оперативную память шлюза, чтобы принудительно закрыть текущий активный WSS-стрим (
/ws/push-stream/{id}) именно для этого девайса, предотвращая утечки памяти и отправку системных пушей на отключенное устройство. - Безопасный сброс стейта UI: Служит триггером для мобильного приложения для полной очистки локальных хранилищ
Secure Storageи переключения интерфейса на стартовый экран авторизации.
2 Протокол взаимодействия (HTTP Контракт)
- Метод:
POST - Маршрут:
/api/v1/auth/logout - Формат данных:
application/json
2.1 Спецификация заголовков (HTTP Headers)
| Заголовок | Обязательный | Описание | Пример значения |
|---|---|---|---|
Content-Type |
Да | Указывает на передачу JSON-пакета | application/json |
Authorization |
Да | Токен доступа (Access Token). Шлюз вычитывает user_id и home_group_id. |
Bearer eyJhbGciOiJIUzI1Ni... |
X-Request-ID |
Да | Сквозной ID запроса для трассировки сессии выхода из системы | req-auth-out-77aa |
2.2 Спецификация тела запроса (Request Body)
В теле запроса клиент явно передает текущий валидный refresh_token, который подлежит удалению в базе данных.
| Поле | Тип | Обязательный | Описание | Пример значения |
|---|---|---|---|---|
refresh_token |
String | Да | Токен обновления, который необходимо аннулировать в СУБД | ref-token-xyz789... |
2.2.1 Пример JSON-запроса (Payload):
{
"refresh_token": "ref-token-xyz789_v1_signature..."
}3 Диаграмма последовательности (Mermaid)
На диаграмме представлена логика безопасного выхода из системы (POST /logout). Сервис Auth блокирует refresh_token в PostgreSQL, после чего шлюз обращается к своему пулу активных соединений и принудительно “тушит” WebSocket-стрим этого смартфона, освобождая оперативную память сервера.
4 Расшифровка шагов
| Шаг | Действие | Параметры / Запросы / DTO | Ошибки (Исключения / Статусы) |
|---|---|---|---|
Шаг 1 (App -> Nginx) |
Пользователь нажимает «Выйти». Клиент отправляет запрос, передавая Access Token в заголовке и текущий Refresh Token в теле для аннулирования. | HTTP POST /api/v1/auth/logoutHeaders: Authorization: Bearer <Access_JWT>Payload ( LogoutRequestDTO):{ "refresh_token": "ref-token-xyz789_v1_signature..." } |
DioException: send timeoutHTTP 401 Unauthorized (токен доступа изменен, подделан или отсутствует) |
Шаг 2 (Nginx -> Gateway) |
Прокси-сервер транслирует команду на отзыв сессии на внутренний API-шлюз с сохранением заголовков. | HTTP POST /backend-api/v1/auth/logoutHeaders: X-Request-ID: "req-auth-out-77aa", Authorization |
HTTP 502 Bad Gateway (контейнер backend-api недоступен)HTTP 504 Gateway Timeout |
Шаг 3 (Gateway -> Auth) |
API-шлюз извлекает user_id и метаданные из токена и направляет gRPC-команду на принудительное аннулирование сессий в контур авторизации. |
Протокол: gRPC Метод: LogoutUser(LogoutRequest)Параметры: refresh_token, user_id |
gRPC Status: UNAVAILABLE (сервис авторизации недоступен)gRPC Status: INVALID_ARGUMENT |
Шаг 4 (Auth -> Redis) |
Инвалидация через Блэклист: Оставшееся время жизни (Remaining TTL) Access-токена вычисляется в памяти сервиса, и токен вносится в Redis Blacklist. |
Redis Команда (Блокировка Access JWT):SET "blacklist:access:eyJhbGci..." "revoked" EX 450 (Где 450 секунд — динамический остаток TTL токена в памяти) |
Fail-Close Аварийный выход: Redis.ConnectionError -> Перехват исключения на бэкенде и возврат HTTP 503 Service Unavailable |
Шаг 5 (Redis -> Auth) |
Redis подтверждает успешную фиксацию и блокировку токена доступа в оперативной памяти кэша. | Ответ кэша: Статус OK. |
Redis.TimeoutError: Command timed out |
Шаг 5 (продолжение) (Auth -> DB_Auth) |
Сервис выполняет деактивацию сессии в PostgreSQL, переводя токен в состояние отозванного по его хэшу. | SQL-запрос:UPDATE user_sessions SET is_revoked = true WHERE refresh_token_hash = 'hash_of_token...' AND user_id = 'user-uuid'; |
PostgreSQL Exception: ConnectionPoolTimeoutPostgreSQL Exception: CommandTimeout |
Подтверждение (DB_Auth -> Auth) |
База данных выполняет изменение статуса строки и подтверждает закрытие сессии. | Ответ СУБД: Статус UPDATE 1 (успешно изменена 1 строка). |
PostgreSQL Exception: DatabaseIsShuttingDownPostgreSQL Exception: TransactionAborted |
Шаг 6 (Auth -> Gateway) |
Сервис авторизации возвращает успешный gRPC-ответ, подтверждая блокировку всех токенов сессии. | Протокол: gRPC Ответ: LogoutResponsePayload: success: true |
gRPC Status: INTERNAL (ошибка маршаллинга gRPC-сообщения) |
Шаг 7 (Gateway -> App) |
Шлюз возвращает финальный успешный HTTP-статус через Nginx, подтверждая полное уничтожение сессии в экосистеме. | HTTP Статус на выходе Nginx: 200 OKResponse Body: { "status": "success", "data": { "message": "SESSION_TERMINATED", "details": "Refresh token successfully revoked. Active WebSocket connection terminated clean.", "timestamp": "2026-07-02T02:20:00Z" } } |
DioException: receive timeout (клиент потерял сеть в момент отправки финального ответа) |
Шаг 8 (App -> App) |
Сброс стейта UI: Мобильное приложение полностью очищает локальное хранилище и переключает интерфейс на экран авторизации. | Внутренний метод приложения:SecureStorage.deleteAll() и мгновенный редирект пользователя на стартовый экран логина. |
SecureStorageException (критическая ошибка очистки Keychain/Keystore на смартфоне) |
5 Спецификация ответов сервера (Response Body) и ошибок
5.1 1. Успешный ответ (Success Response)
5.1.1 HTTP 200 OK (Ответ на Шаге 8)
Возвращается мобильному приложению после успешного коммита транзакции деактивации. В теле ответа фиксируется успешное удаление сессии.
- Заголовки ответа (Response Headers):
Content-Type: application/json
- Тело ответа (Response Body):
{
"status": "success",
"data": {
"message": "SESSION_TERMINATED",
"details": "Refresh token successfully revoked. Active WebSocket connection terminated clean.",
"timestamp": "2026-07-02T02:20:00Z"
}
}