Сравните аутентификацию по сессиям и по JWT. Как безопасно хранить токен и что делать с отзывом?
Короткий ответ
- Сессия: id в cookie, состояние на сервере, отзыв тривиален
- JWT: подписанный самодостаточный токен, сервер не хранит состояние
- JWT нельзя отозвать до истечения — нужны короткий TTL и refresh-токены
- Хранение в браузере: httpOnly secure cookie против XSS-кражи
- Для cookie нужна защита от CSRF (SameSite, токены)
- Подпись проверять обязательно, алгоритм none — классическая дыра
Сессии проще и легко отзываются, JWT удобен для распределённых систем, но требует короткого TTL и схемы refresh.
Как сказать вслух
пример ответаПри сессионной схеме сервер хранит состояние, а клиенту отдаёт только идентификатор в cookie — отозвать доступ просто, достаточно удалить сессию. JWT — это подписанный токен, в котором уже лежат данные о пользователе, и серверу не нужно ходить в хранилище — удобно для микросервисов. Но у JWT есть минус: его нельзя отозвать до истечения срока. Поэтому делают короткоживущий access-токен и refresh-токен, а в браузере хранят токены в httpOnly cookie, чтобы их не украли через XSS.
Подробный ответ
Основной ответ
Сессии: после логина сервер создаёт запись (в памяти, Redis, базе) и кладёт её id в httpOnly cookie. Плюсы — мгновенный отзыв, маленький cookie; минус — общее хранилище сессий при горизонтальном масштабировании. JWT — самодостаточный токен из header.payload.signature: сервис проверяет подпись (HMAC или RSA/ECDSA) и доверяет клеймам без обращения к хранилищу, что удобно между микросервисами и для сторонних клиентов. Главная проблема — отзыв: токен валиден до exp. Стандартное решение — access-токен на минуты плюс refresh-токен с ротацией и возможностью отзыва на сервере; для жёстких требований — чёрный список jti или короткий кэш отозванных. Хранение в браузере: httpOnly + Secure + SameSite cookie защищает от кражи через XSS; localStorage уязвим. Payload JWT только закодирован base64, не зашифрован — секретов там быть не должно.
Ключевые моменты
- Stateless — это компромисс. Отсутствие хранилища упрощает масштабирование, но отбирает мгновенный отзыв; refresh-схема возвращает контроль.
- Access + refresh. Access живёт 5–15 минут, refresh — дольше, хранится строже и ротируется при каждом использовании; кража refresh детектится по повторному использованию.
- XSS vs CSRF. Cookie уязвим к CSRF (лечится SameSite и CSRF-токенами), заголовок Authorization — к XSS при хранении в localStorage. Выбор хранения — выбор угрозы.
- Проверка подписи. Валидировать alg из белого списка, не принимать none, проверять exp, iss, aud; ключи ротировать через kid/JWKS.
Практический контекст
В монолите с одним доменом сессии в Redis часто проще и безопаснее. JWT оправдан в микросервисах, мобильных API и при интеграции через OAuth2/OIDC, где он и так является форматом access-токена. Интервьюер почти всегда задаёт два контрольных вопроса: «как разлогинить пользователя с JWT» и «где хранить токен в браузере» — по ответам видно реальный опыт с безопасностью.
Частые ошибки
- Кладут в payload JWT чувствительные данные, думая, что он зашифрован
- Не могут ответить, как отозвать JWT при компрометации аккаунта
- Хранят токен в localStorage и не упоминают риск XSS