Битлента
Словарь терминов3 мин чтения·

JWT: из чего состоит токен и как его безопасно использовать

Как устроен JSON Web Token: заголовок, полезная нагрузка и подпись. Чем подпись отличается от шифрования и какие ошибки делают JWT уязвимым.

Три части через точки

JWT, JSON Web Token, это компактный формат токена, описанный в RFC 7519. Внешне он выглядит как длинная строка из трёх частей, разделённых точками. Каждая часть закодирована способом Base64URL, поэтому строку можно безопасно передавать в заголовке запроса или в адресе.

Первая часть это заголовок: в нём указан тип токена и алгоритм подписи. Вторая часть это полезная нагрузка, набор утверждений в формате JSON: кто выдал токен, для кого он предназначен, для какого пользователя, до какого времени действует. Третья часть это подпись, вычисленная над первыми двумя с помощью секретного ключа или пары ключей.

Подпись не значит секретность

Самое частое заблуждение: думать, что содержимое JWT скрыто. Base64URL это не шифрование, а способ записи. Любой, кто получил токен, может раскодировать заголовок и нагрузку и прочитать их. Поэтому в нагрузку нельзя класть пароли, номера карт и другие секреты.

Подпись обеспечивает совсем другое: целостность и подлинность. Если кто-то изменит хотя бы один символ нагрузки, подпись перестанет совпадать, и сервер отвергнет токен. Для скрытия содержимого существует отдельный вариант JWE, шифрованный токен, но в повседневных схемах встречается гораздо реже подписанного.

Подписи: общий секрет или пара ключей

Алгоритм подписи выбирается в заголовке. Семейство HMAC, например HS256, использует один общий секрет, и проверять подпись может только тот, кто им обладает. Алгоритмы на основе асимметричных ключей, RS256 или ES256, подписывают закрытым ключом, а проверить может любой владелец открытого, что удобно, когда токены выпускает один сервис, а принимают многие.

Проверка на стороне сервера включает не только подпись. Нужно сверить издателя, предполагаемого получателя и срок действия. Токен без проверки срока действует вечно, а токен без проверки получателя можно применить не там, где его выдавали.

🛡️ Остались проблемы с соединением?
Можно пользоваться постоянно: российские приложения работают, включать и выключать ничего не нужно. Без карты и регистрации, настройка за пару минут.
Попробовать бесплатно

Типичные ошибки: JWT

Известные уязвимости связаны с реализацией. Некоторые библиотеки принимали токены с алгоритмом «none», то есть без подписи, если сервер доверял заявленному в заголовке значению. Другая ошибка это подмена алгоритма: атакующий меняет асимметричный на симметричный и подписывает токен открытым ключом, который сервер по ошибке использует как общий секрет. Защищаться нужно тем, что сервер сам задаёт разрешённые алгоритмы, а не читает их из токена.

Третья проблема практическая: токен нельзя аннулировать до истечения срока без дополнительного механизма, поскольку сервер не хранит состояния. Поэтому делают короткий срок жизни и выдают отдельные токены обновления, а для срочного отзыва ведут список аннулированных.

Где хранить и как смотреть

Место хранения на клиенте это компромисс. В хранилище браузера токен доступен скриптам и уязвим при XSS. В cookie с флагами HttpOnly и Secure он защищён от скриптов, но тогда нужно продумывать защиту от подделки межсайтовых запросов. Универсального ответа нет, выбор зависит от архитектуры приложения.

Заглянуть внутрь токена можно в инструментах разработчика браузера на вкладке с запросами или в хранилище. Раскодируйте среднюю часть любым Base64-декодером: вы увидите утверждения. Не вставляйте действующие токены в сторонние онлайн-сервисы: токен работает как ключ, пока не истёк.

Обязательные утверждения

В нагрузке JWT есть стандартные поля, называемые зарегистрированными утверждениями. Поле iss указывает издателя, sub обозначает субъекта, обычно пользователя, aud получателя, exp момент истечения срока, nbf время, раньше которого токен недействителен, iat время выпуска, а jti уникальный идентификатор токена. Остальные поля определяет приложение, например роли.

Хорошая практика это всегда проверять exp, iss и aud, использовать небольшой запас на расхождение часов и не помещать в токен лишних данных. Чем короче токен, тем меньше он утяжеляет каждый запрос, ведь его отправляют вместе со всеми обращениями к API.

Полезно помнить, что размер токена растёт вместе с числом утверждений, а заголовки запросов имеют ограничения на длину у серверов и прокси. Слишком раздутый токен может приводить к ошибкам, которые трудно связать с самой аутентификацией.

🛡️ Остались проблемы с соединением?
Можно пользоваться постоянно: российские приложения работают, включать и выключать ничего не нужно. Без карты и регистрации, настройка за пару минут.
Попробовать бесплатно
jwtтокеныаутентификацияразработка

Часто задаваемые вопросы

Читайте также