Сессия держит состояние на сервере: отозвать её проще — удалили ключ в store. JWT access самодостаточен после подписи; отзыв сложнее. HS256 делит секрет с каждым, кто проверяет. RS256 оставляет подпись у issuer. Где хранить токен — развилка XSS против CSRF.
Авторизация и устойчивость HTTP http собеседование
Классическая сессия: cookie с непрозрачным id. Сервер (или Redis) хранит id → пользователь. Горизонталь требует общего store. Отзыв простой: удалили ключ — следующий запрос неаутентифицирован. Цена — lookup на каждый запрос.
JWT access: заголовок, payload (claims), подпись. Resource server может проверить подпись и exp без похода в БД. Удобно между сервисами. Минус: до истечения TTL токен жив, даже если пользователя уже разлогинили. Нужны короткий TTL, blocklist, версия в claim или интроспекция.
OAuth2 — делегирование доступа. Клиент получает access (и часто refresh) у authorization server. Resource server проверяет access. Это не синоним «самописный логин, который кладёт JWT в localStorage». OpenID Connect добавляет идентичность поверх OAuth.
HS256 и RS256
HS256 — HMAC с общим секретом. Любой, у кого есть секрет, может и проверить, и подписать. Если десять сервисов «просто проверяют» одним ключом, компрометация любого из них — фабрика токенов.
RS256/ES256: приватный ключ у issuer, публичный у всех проверяющих. Resource server не умеет ковать токены.
Пример. Сервис отзывов хранит тот же HMAC-секрет, что и auth. Его взломали. Злоумышленник подписывает access с sub=admin. Все остальные сервисы принимают токен: секрет тот же. С RS256 у сервиса отзывов только публичный ключ. Подделать токен он не может.
// JWT: header.payload.signature
// HS256: HMAC(secret, data) — secret есть у всех «проверяющих»
// RS256: sign(private_issuer, data); verify(public, …)
//
// сессия: DELETE session:abc → отзыв сразу
// JWT access TTL 5m: отзыв = blocklist / ver claim / подождать exp
//
// localStorage: любой XSS читает токен
// Set-Cookie HttpOnly; Secure; SameSite=Lax → JS не видит, нужен CSRF
Access короткий, refresh длиннее. HS256: секрет умеет подписывать. httpOnly cookie не виден JS, но нужен CSRF-контроль.
Refresh и хранение
Access живёт минуты. Refresh — дольше и хранится строже: httpOnly cookie, ротация при каждом использовании. Refresh в localStorage рядом с access — длинный ключ для XSS. Не кладите пароль или персональные данные в payload «без проверки подписи».
XSS против CSRF
Токен в localStorage удобен SPA: JS сам ставит Authorization. Любой XSS крадёт его. Cookie с HttpOnly JS не читает — XSS не вытащит токен простым скриптом. Но браузер приложит cookie к запросу: нужна защита CSRF (SameSite, anti-CSRF token). Это главная развилка, не «cookie всегда неуязвим».
Типичная ошибка
Сказать «JWT безопаснее сессии». Безопасность зависит от TTL, алгоритма, места хранения и отзыва. HS256 «для всех микросервисов одним секретом» превращает каждый сервис в issuer.
На собеседовании
Сессию отозвать проще: ключ из store. Access короткий, refresh длинный, между сервисами — асимметрия (RS256). XSS крадёт JS-хранилище; httpOnly cookie требует CSRF-контроль. OAuth — про делегирование, не про «просто JWT».