JWT и JWKS: как проверить токен
JWT расшифровывается как JSON Web Token. Это компактный формат подписанного сообщения, в котором передаются claims.
JWKS расшифровывается как JSON Web Key Set — набор ключей JSON Web. Это JSON-документ с публичными ключами, с помощью которых проверяют подпись JWT.
Проще говоря, JWT — это подписанное сообщение с данными, а JWKS — опубликованный набор ключей для проверки подписи этого сообщения. Вместе они позволяют API и OIDC-клиенту не просто прочитать токен, а проверить, что его выпустил доверенный сервер и что содержимое не изменилось.
Если нужно только понять разницу между ID Token, Access Token и Refresh Token, начните со статьи о токенах. Эта статья нужна, когда вы пишете проверку токена или разбираете ошибку подписи.
JWT не равен «зашифрованному токену»
JWT обычно выглядит так:
header.payload.signature
Три части разделены точками и кодируются Base64URL:
- header описывает тип сообщения, алгоритм подписи и иногда идентификатор ключа
kid; - payload содержит claims: например
sub,iss,audиexp; - signature подтверждает, что header и payload подписаны соответствующим ключом.
Base64URL — это кодирование, а не шифрование. Человек, получивший JWT, может декодировать header и payload. Поэтому секреты, пароли и другие данные, которые нельзя показывать владельцу токена, нельзя помещать в обычный JWT.
Подлинность определяется не тем, что payload выглядит правдоподобно, а корректностью signature. Изменение даже одного символа в payload должно сделать подпись недействительной.
Как устроена проверка подписи
Упрощённо сервер выполняет следующие действия:
- получает JWT из запроса;
- разбирает header и определяет алгоритм и
kid; - выбирает публичный ключ из JWKS;
- проверяет signature над исходными header и payload;
- проверяет claims и назначение токена;
- только после этого передаёт субъект в бизнес-логику.
Проверка подписи и проверка claims — разные операции. Настоящий токен с истёкшим
exp должен быть отклонён так же, как токен с неправильной подписью.
Что такое JWKS
Как уже говорилось, JSON Web Key Set - это JSON-документ с публичными ключами сервера. OIDC provider публикует его URI в discovery document, чтобы клиент не хранил один ключ в исходном коде.
У ключа обычно есть kid, kty, параметры алгоритма и материал публичного ключа.
При проверке JWT приложение смотрит на kid в header и выбирает соответствующий
ключ из набора.
JWT header: Discovery document:
{ "alg": "RS256", { "jwks_uri": ".../jwks" }
"kid": "key-2026-01" } |
| v
+--------------------> JWKS
key-2026-01
Приложение не получает private key. Private key остаётся у issuer и используется для подписи. JWKS содержит только материалы, достаточные для проверки подписи.
Зачем нужна ротация ключей
Сервер может заменить ключ подписи. Например, старый ключ нужно вывести из эксплуатации или плановая ротация происходит по политике безопасности. Поэтому проверяющий клиент должен:
- учитывать
kid; - уметь обновить JWKS;
- не привязываться к одному ключу навсегда;
- не принимать алгоритм, который приложение не разрешало;
- корректно обрабатывать короткий период, когда старый и новый ключи доступны одновременно.
Не копируйте один публичный ключ в конфигурационный файл как постоянное решение, если библиотека поддерживает JWKS. Discovery и JWKS обычно обрабатываются OIDC-библиотекой автоматически.
Проверка ID Token
OIDC-клиент проверяет ID Token как результат аутентификации. Помимо подписи обычно проверяются:
iss— ожидаемый issuer;aud— client ID приложения;exp— срок действия;iat— время выпуска;nonce— связь с текущим authentication flow;- допустимый алгоритм подписи.
После проверки приложение может использовать sub для поиска локальной учётной
записи. Нельзя создавать сессию, сначала прочитав email из неподписанного payload.
Проверка Access Token
Resource server проверяет Access Token в контексте своего API. Ему важно убедиться, что токен выпущен доверенным issuer, предназначен нужной audience и не истёк. После криптографической проверки API отдельно принимает решение о праве пользователя на конкретную операцию.
Access Token и ID Token могут иметь одинаковый формат JWT, но это не делает их взаимозаменяемыми. Назначение токена определяется контрактом и claims, а не только тем, что его удалось декодировать.
Типичные ошибки
Декодировать JWT вместо проверки
Декодирование показывает содержимое, но не подтверждает подпись. Такой payload нельзя использовать для входа или разрешения операции.
Доверять алгоритму из header
Header приходит от клиента и не должен единолично определять допустимый алгоритм. Список алгоритмов задаётся конфигурацией проверяющей стороны и контрактом issuer.
Игнорировать kid
При ротации ключей проверка фиксированным ключом начнёт случайно отклонять новые токены или, что хуже, приложение попытается выбрать неправильный ключ.
Проверять только exp
Незавершённая проверка срока не отвечает на вопросы о подписи, issuer и audience. Нужен полный validation через OIDC-библиотеку или проверенный JWT-инструмент.
Как диагностировать ошибку
Проверяйте в таком порядке:
- токен действительно передан в заголовке
Authorization; - JWT состоит из трёх частей и не повреждён при передаче;
- issuer и discovery относятся к нужной среде;
- JWKS доступен и содержит ключ с нужным
kid; - алгоритм разрешён конфигурацией;
- подпись проходит проверку;
iss,aud,expи остальные обязательные claims корректны;- после этого выполняется проверка бизнес-права.
Не публикуйте полный токен в логах при диагностике. Достаточно записать код ошибки,
issuer, kid и безопасные метаданные запроса.
Как проверить результат
- изменённый payload отклоняется;
- токен с другим issuer отклоняется;
- истёкший токен отклоняется;
- при ротации ключа новый
kidобрабатывается после обновления JWKS; - ID Token не принимается вместо Access Token;
- успешная криптографическая проверка не пропускает пользователя без бизнес-проверки.
Как это связано с Authoriza
SDK Authoriza получает discovery и JWKS, выбирает публичный ключ по kid и
проверяет ID Token перед созданием пользовательской сессии. Для собственного API
применяйте валидатор, который поддерживает JWKS, и проверяйте Access Token по
правилам resource server.
Чем Authoriza может быть полезна
Если вы хотите подключить OIDC без ручной реализации discovery, JWKS и проверки ID Token, SDK Authoriza выполняет эти операции внутри authentication flow. Для самостоятельного API-сценария сначала изучите раздел о токенах, а затем используйте подтверждённую библиотеку для проверки Access Token.