JWT: что на самом деле в этих длинных строках
JSON Web Tokens декодированы. Как они работают, что содержат и частые ошибки безопасности.
Ты видишь строку вроде eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U в своей системе аутентификации.
Что это? Это JWT — три Base64-кодированных куска, разделённых точками. И ты можешь прочитать это без каких-либо специальных ключей.
Три части
Заголовок: Алгоритм и тип токена
{"alg": "HS256", "typ": "JWT"}
Полезная нагрузка: Фактические данные (утверждения)
{"sub": "1234567890", "name": "John", "iat": 1516239022}
Подпись: Проверка, что ничего не было изменено
JWT не зашифрованы
Это главное. Любой может декодировать JWT и прочитать его содержимое. Base64 — это кодирование, а не шифрование.
Не помещай секреты в JWT. ID пользователей, права, время истечения — нормально. Пароли, кредитные карты, приватные данные — никогда.
Стандартные утверждения
iss — Issuer / Издатель. Кто создал этот токен.
sub — Subject / Субъект. Обычно ID пользователя.
exp — Expiration / Истечение. Unix timestamp, когда токен становится невалидным.
iat — Issued at / Выпущен в. Когда токен был создан.
aud — Audience / Аудитория. Кто должен принимать этот токен.
Пользовательские утверждения тоже работают. Добавляй любые данные, которые нужны твоему приложению.
Как работают подписи
Подпись доказывает, что токен не был изменён.
Сервер создаёт токен → подписывает секретным ключом → отправляет клиенту. Клиент отправляет токен обратно → сервер проверяет подпись → доверяет содержимому.
Если кто-то изменит полезную нагрузку, подпись не совпадёт. Сервер отклонит его.
Но сервер должен проверять подпись. JWT без проверки — это видимость безопасности.
Частые ошибки безопасности
Не проверяешь подписи. Некоторый код декодирует JWT без проверки подписи. Любой может подделать токены.
Использование слабых секретов. secret123 — это не секрет. Используй длинные, случайные строки.
Игнорирование истечения. Всегда проверяй exp. Токены должны иметь короткое время жизни.
Путаница алгоритмов. Поле alg говорит, как проверять. Атакующие могут установить его на none и пропустить проверку, если твой код доверяет заголовку.
Хранение чувствительных данных. Любой с токеном может прочитать полезную нагрузку. Держи секреты на стороне сервера.
Когда использовать JWT
Stateless аутентификация. Серверу не нужно хранить сессии. Токен содержит всё необходимое.
Микросервисы. Сервисы могут проверять токены без вызова сервера аутентификации.
Единый вход. Делись аутентификацией между доменами.
Когда не использовать JWT
Простые приложения. Сессионные куки проще и сложнее испортить.
Нужно немедленно аннулировать. JWT валидны до истечения. Отзыв требует дополнительной инфраструктуры.
Большие полезные нагрузки. Каждый запрос несёт полный токен. Большие токены означают больше трафика.
Токены обновления
Токены доступа должны быть короткоживущими (минуты-часы). Токены обновления получают новые токены доступа без повторной аутентификации.
Храни токены обновления безопасно. Они долгоживущие и мощные.
JWT удобны, но требуют осторожности. Пойми, что они содержат, правильно проверяй подписи, устанавливай короткие сроки истечения и никогда не помещай чувствительные данные в полезную нагрузку.