sequenceDiagram
autonumber
actor User as Веб-клиент
participant NGINX as NGINX
participant Auth as R Gatekeeper
participant DB as Postgres (Auth DB)
participant Shiny as Shiny App
Note over User, DB: Этап 1: Авторизованная сессия
User->>NGINX: GET /api/data (Bearer AccessToken)
NGINX->>Auth: Валидация
Auth-->>NGINX: 200 OK
NGINX->>Shiny: Запрос данных
Shiny-->>User: Данные дашборда
Note over User, DB: Этап 2: Выход из системы (Logout)
User->>NGINX: POST /auth/logout
Note right of User: Отправляет RefreshToken в Cookie
NGINX->>Auth: Перенаправление на /logout
Auth->>DB: UPDATE refresh_tokens SET revoked = TRUE <br/>WHERE token = $1
DB-->>Auth: Успешно отозван
Auth-->>NGINX: 200 OK + Clear-Cookie
NGINX-->>User: 200 OK (Сессия завершена)
Note over User, DB: Этап 3: Попытка кражи (Replay Attack)
User->>NGINX: POST /auth/refresh (Украденный RefreshToken)
NGINX->>Auth: Проверка токена
Auth->>DB: SELECT * FROM refresh_tokens WHERE token = $1
DB-->>Auth: Токен найден, но REVOKED = TRUE
Auth-->>NGINX: 403 Forbidden
NGINX-->>User: 403 Forbidden (Доступ запрещен)
Безопасность: Обновление и Отзыв токенов
Механизм Logout и Revocation в системе Shiny/Gatekeeper
1. Механизм отзыва (Revocation)
Для обеспечения полной безопасности выход из системы (Logout) не должен просто удалять токен на клиенте. Сервер обязан аннулировать Refresh Token в базе данных, чтобы он больше не мог быть использован для генерации новых сессий.
2. Полная диаграмма последовательности
3. Обновленная структура базы данных
Для поддержки отзыва токенов таблица в Postgres должна выглядеть следующим образом:
Показать пример таблицы токенов
| Поле | Тип | Описание |
|---|---|---|
token_hash |
TEXT (PK) | Хэш Refresh-токена для поиска. |
user_id |
INT | Ссылка на пользователя. |
expires_at |
TIMESTAMP | Время истечения срока жизни. |
is_revoked |
BOOLEAN | Флаг аннулирования (ставится при Logout). |
replaced_by |
TEXT | (Опционально) ID нового токена для отслеживания цепочки ротации. |
4. Задачи по реализации
Важное уведомлениеКритические изменения
- SES-007: Создать эндпоинт
/auth/logout, который принимает Refresh Token и помечает его какrevokedв БД. - SES-008: Обновить логику
/auth/refresh— перед выдачей нового Access Token обязательно проверять флагis_revoked. - SES-009: Настроить автоматическую очистку (Cron) старых и отозванных токенов из БД раз в сутки.
Заключение
Механизм Revocation гарантирует, что сессия пользователя действительно прекращается в момент нажатия кнопки «Выход». Даже если злоумышленник перехватил Refresh Token ранее, после Logout он станет бесполезным.
Рекомендация: Для Shiny-приложения стоит добавить таймер неактивности, который будет автоматически вызывать /logout через 30 минут отсутствия действий пользователя.