Жизнь токена: почему Access Token на 24 часа — преступление
Выпустить JWT со сроком жизни на сутки или неделю — верный способ превратить утечку в катастрофу, которую невозможно остановить. Разбираем, почему Access Token должен жить 5–15 минут, и как правильно настроить ротацию Refresh Token.

В девяти из десяти веб-приложений и микросервисных архитектур, созданных за последние пять лет, в конфигурационном файле авторизации красуется вот такая строчка:
{
"jwt_access_token_ttl": "86400s", // 24 часа
"jwt_refresh_token_ttl": "2592000s" // 30 дней
}
Разработчик, писавший этот код, рассуждал просто: *«Если поставить токен на 10 минут, пользователей будет постоянно выбрасывать из системы, саппорт завалят тикетами, а мобилка начнёт лагать. Поставим сутки — и никаких проблем!»*.
Проблем действительно нет. Ровно до того момента, пока этот токен впервые не утечёт.
Давайте разберёмся, почему Access Token со сроком жизни 24 часа — это бомба замедленного действия, и как нормальные инженеры балансируют между комфортом пользователей и реальной безопасностью.
---
Проклятие самодостаточности: почему JWT нельзя отозвать
В чём главная прелесть JSON Web Token (JWT)? Он не требует состояния (stateless).
Токен содержит внутри себя все данные: кто вы (sub), какие у вас права (roles), когда он выдан (iat) и когда протухнет (exp). Токен подписан асимметричным ключом (RS256 или Ed25519).
Любой ваш микросервис — от биллинга до профиля — может взять этот токен, проверить математическую подпись по публичному ключу и сказать: *«Да, токен валиден, добро пожаловать»*. Микросервису не нужно делать запрос в базу данных или обращаться к центральному серверу авторизации. Быстро, масштабируемо, надёжно.
Но в этом же кроется и фатальная уязвимость.
Представьте:
1. Ноутбук сотрудника заражён инфостилером, или токен попал в логи прокси-сервера из-за кривого заголовка;
2. Злоумышленник скопировал Access Token себе;
3. Вы заметили подозрительную активность, заблокировали сотрудника в Active Directory и сменили ему пароль.
Знаете, что произойдёт с украденным токеном? Ничего.
Микросервисы понятия не имеют, что сотрудника уволили или сменили ему пароль. Они не смотрят в Active Directory. Они просто проверяют математическую подпись токена и дату в поле exp. И пока 24 часа не истекут, злоумышленник будет спокойно скачивать базы клиентов, выгружать репозитории и дергать продакшн-API от имени скомпрометированного сотрудника.
---
Попытки починить проблему костылями
Когда до команды доходит осознание этой проблемы, начинаются судорожные попытки построить костыли:
Костыль 1. «Чёрные списки» (Blacklists) в Redis
Админы поднимают Redis и при каждом логауте записывают ID отозванного токена (jti). Теперь микросервис перед выполнением запроса идёт в Redis проверить, не отозван ли токен.
*Поздравляем: вы только что убили главную фичу JWT и вернулись к классическим тяжелым сессиям в общей базе данных, потеряв всю производительность.*
Костыль 2. Смена приватного ключа сервера
Паникующий техлид нажимает кнопку «Перегенерировать ключ подписи JWT».
*Итог: все 100% сотрудников компании в эту же секунду вылетают из всех рабочих сервисов с ошибкой авторизации, парализуя работу бизнеса.*
---
Как это устроено по стандарту: Access + Refresh Flow
Безопасная архитектура токенов строится на чётком разделении ролей (OAuth 2.0 Security BCP):
┌─────────────────────────────────────────────────────────────┐
│ БРАУЗЕР / КЛИЕНТ │
│ │
│ [Access Token] (в памяти JS) [Refresh Token] │
│ • Живёт 5–15 минут • Живёт дни/недели │
│ • Для каждого запроса к API • В защищённой HttpOnly │
│ SameSite Secure куке │
└──────────────────────────┬──────────────────────┬───────────┘
│ │
Каждые 5-15 мин │ Раз в 15 минут
к микросервисам ▼ за новым Access
│ ┌────────────────────┐
▼ │ [Шлюз OwnGate] │
┌──────────────┐ │ │
│ Микросервисы │ │ Проверяет AD / MFA │
│ (Валидация │ │ и ротирует токены │
│ по JWKS) │ └────────────────────┘
└──────────────┘
1. Access Token живёт 5–15 минут
Короткий срок жизни — это ваше окно допустимого риска. Даже если токен каким-то чудом перехватили из памяти браузера, через 5–10 минут он превратится в бесполезный мусор.
2. Токен не хранится в localStorage
Никогда не храните токены в localStorage или IndexedDB. Любая XSS-уязвимость на странице (например, в сторонней библиотеке аналитики) позволяет скрипту прочитать localStorage в одну строчку. Токен должен жить только в оперативной памяти рантайма.
3. Ротация Refresh Token (Refresh Token Rotation)
Каждый раз, когда приложение обращается к шлюзу OwnGate за новым Access Token, старый Refresh Token уничтожается, а клиенту выдаётся новая пара.
Если злоумышленник украл Refresh Token и попытался им воспользоваться, а через минуту легитимный клиент попробует обновиться старым токеном — шлюз мгновенно распознает конфликт (Reuse Detection) и аннулирует всю цепочку сессий, выбросив взломщика наружу.
---
Что в итоге
Безопасность авторизации — это не про выбор между «безопасно» и «удобно».
В шлюзе OwnGate короткоживущие Access-токены обновляются в фоновом режиме через Web Workers или защищённые куки абсолютно незаметно для сотрудника. Никто не видит мерцания экрана и не вводит пароль каждые 15 минут.
Но если инженера уволили или устройство попало не в те руки — доступ испаряется за считанные минуты, а не через сутки после катастрофы.