Введение
JSON Web Token (JWT) – популярный метод аутентификации в современных веб-приложениях и API. Его главное преимущество – stateless-архитектура, которая не требует хранения сессий на сервере. Однако у JWT есть серьезный недостаток: токен нельзя отозвать до истечения срока его действия.
В этой статье разберем:
- Как работает JWT?
- Почему его нельзя просто так отозвать?
- 5 практических способов обезопасить систему и добавить механизмы отзыва.
1. Как устроен JWT?
JWT состоит из трех частей:
Header.Payload.Signature
- Header – тип токена и алгоритм подписи (например,
HS256
). - Payload – полезные данные (например,
user_id
,email
,role
). - Signature – подпись, которая гарантирует целостность токена.
После аутентификации сервер выдает клиенту JWT, который тот отправляет в заголовке Authorization: Bearer <token>
.
Проблема:
Если токен украден, злоумышленник может использовать его, пока он не протухнет. Сервер не может принудительно отозвать JWT, потому что он не хранит его состояние.
2. Способы «отзыва» JWT
🔹 1. Короткое время жизни (TTL)
Идея: Access Token живет 15-30 минут, после чего становится невалидным.
Плюсы:
✅ Простота реализации.
✅ Минимизация ущерба при утечке.
Минусы:
❌ Пользователю придется часто обновлять токен.
Когда использовать:
- Внутренние API с низкими требованиями к безопасности.
🔹 2. Refresh Token + Access Token
Схема:
- Access Token (JWT) – короткоживущий (15-30 мин), дает доступ к API.
- Refresh Token – долгоживущий (неделя/месяц), хранится в HttpOnly-куках и используется для получения нового Access Token.
Как работает:
- После входа пользователь получает:
{
"access_token": "eyJ...", // JWT на 15 мин
"refresh_token": "a1b2c3..." // Рандомная строка
}
- При истечении Access Token клиент отправляет Refresh Token на
/refresh
. - Сервер проверяет его в БД и выдает новый Access Token.
Если токен украден:
- Удаляем Refresh Token из базы → злоумышленник не сможет получить новый Access Token.
Плюсы:
✅ Баланс безопасности и удобства.
✅ Можно отозвать доступ через Refresh Token.
Минусы:
❌ Нужно хранить Refresh Token в БД (частичная потеря stateless).
Когда использовать:
- Подавляющее большинство современных веб-приложений.
🔹 3. Blacklist (список недействительных токенов)
Идея: При логауте или подозрительной активности сервер заносит JWT в черный список (Redis / БД).
Как работает:
- Пользователь выходит → токен попадает в
jwt_blacklist
. - При каждом запросе сервер проверяет, не в черном списке ли токен.
Плюсы:
✅ Полный контроль над отзывом.
Минусы:
❌ Потеря stateless-преимущества JWT.
❌ Дополнительные запросы к БД при каждом обращении.
Когда использовать:
- Критически важные системы.
🔹 4. Гибридный подход (JWT + сессии)
Идея:
- В JWT хранится только ID сессии, а данные пользователя лежат в БД.
- При логауте сессия удаляется → токен становится бесполезным.
Плюсы:
✅ Полный контроль над сессиями.
Минусы:
❌ Фактически это уже не чистый JWT.
Когда использовать:
- Если нужна максимальная безопасность без полного отказа от JWT.
🔹 5. Динамический ключ подписи (Key Rotation)
Идея: Сервер периодически меняет секретный ключ, которым подписываются JWT.
Эффект:
- Все старые токены автоматически становятся невалидными.
Плюсы:
✅ Массовый «отзыв» всех токенов.
Минусы:
❌ Все пользователи будут разлогинены.
Когда использовать:
- При смене системы безопасности (например, после утечки).
3. Что выбрать?
Метод | Stateless? | Можно отозвать? | Сложность |
---|---|---|---|
Короткий TTL | ✅ Да | ❌ Нет | Низкая |
Refresh + Access | ⚠️ Частично | ✅ Да | Средняя |
Blacklist | ❌ Нет | ✅ Да | Высокая |
Гибрид (JWT + сессии) | ❌ Нет | ✅ Да | Высокая |
Key Rotation | ✅ Да | ✅ Да (все сразу) | Средняя |
Рекомендации:
- Для большинства проектов → Refresh Token + Access Token.
- Высокие требования к безопасности → Blacklist или гибридный подход.
- Экстренные случаи → Key Rotation.
Заключение
JWT – удобный инструмент, но его нельзя просто отозвать. Однако с помощью короткого TTL, Refresh Token, Blacklist или гибридных схем можно добиться безопасной аутентификации.
Какой метод используете вы? Делитесь в комментариях! 🚀
Добавить комментарий