Разработка

Как декодировать и отлаживать JWT

JSON Web Token — это всего три части, закодированные в Base64URL. Когда вы научитесь их читать, большинство ошибок «invalid token» станут понятны за несколько секунд. В этом руководстве показано, как декодировать JWT, проверить claims, которые чаще всего ломаются, и какие ошибки превращают JWT в уязвимость.

Начинающий · Чтение: 7 мин · Обновлено 30 октября 2026 г.

Как декодировать и отлаживать JWT

Из чего состоит JWT

JWT выглядит как xxxxx.yyyyy.zzzzz. Три части, разделённые точками, это:

  1. Header (заголовок) — JSON с алгоритмом подписи (alg) и типом токена, например {"alg":"HS256","typ":"JWT"}.
  2. Payload (полезная нагрузка) — JSON с claims: о ком токен и когда он действителен.
  3. Signature (подпись) — хеш первых двух частей, созданный с помощью секрета (HMAC) или закрытого ключа (RSA, ECDSA).

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

Декодирование токена

Вставьте токен в JWT Decoder, и он покажет заголовок, payload и все временные метки в виде понятных дат. Всё работает в вашем браузере, поэтому рабочие токены никуда не отправляются. Чтобы декодировать вручную, выполните Base64URL-декодирование каждой части: замените - на +, _ на / и добавьте padding. Или в Node:

const [header, payload] = token.split('.').slice(0, 2)
  .map(part => JSON.parse(Buffer.from(part, 'base64url').toString()));
console.log(header, payload);

Claims, которые ломаются чаще всего

ClaimЗначениеТипичная ошибка
expСрок действия, Unix-секунды«jwt expired»: проверьте также часы на сервере и клиенте
nbfНе действителен доТокен использовали на несколько секунд раньше, потому что часы издателя спешат
iatВремя выпускаОтклонён как «issued in the future» из-за расхождения часов
audАудитория, для которой предназначен токенТокен для одного API отправлен на другой: проверяющая сторона обязана это проверить
issИздательПерепутаны издатели dev и production

Временные метки указаны в секундах, а не в миллисекундах. Если срок истечения выглядит как 55 000 год, кто-то написал Date.now() вместо Math.floor(Date.now() / 1000). Для проверки подойдёт Unix Timestamp Converter. Большинство библиотек допускают небольшую погрешность часов (30–60 секунд), чтобы компенсировать расхождение между серверами.

Почему «invalid signature»?

  • Неверный секрет или ключ — самая частая причина. Проверьте переменную окружения на сервере, который выполняет проверку, а не только на том, который подписывает.
  • Неверный алгоритм — токен, подписанный RS256, проверяется как HS256, или наоборот.
  • Токен был изменён — изменение одного символа в payload ломает подпись, и это как раз задумано.
  • Ротация ключей — ключи издателя изменились. При использовании JWKS сопоставьте kid из заголовка с опубликованным ключом.

Чтобы проверить токен HS256 вручную, вычислите HMAC-SHA256 от header.payload с секретом в HMAC Generator и сравните результат в кодировке Base64URL с третьей частью.

Ошибки безопасности, которых стоит избегать

  • Декодирование — это не проверка. Никогда не доверяйте claims из jwt.decode(); используйте функцию verify вашей библиотеки с явным списком разрешённых алгоритмов.
  • Отклоняйте alg: none и фиксируйте алгоритм. Никогда не позволяйте токену решать, как его проверять.
  • Делайте токены короткоживущими (access-токены — минуты) и используйте refresh-токены для длинных сессий. JWT нельзя отозвать до истечения срока без дополнительного состояния на сервере.
  • Не храните токены в localStorage, если XSS-уязвимость может их прочитать. Для браузерных приложений безопаснее cookie с флагами HttpOnly, Secure и SameSite.

Нужен тестовый токен с определёнными claims? Создайте его с помощью JWT Encoder.

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

Может ли кто-нибудь прочитать мой JWT?
Да. Header и payload лишь закодированы в Base64URL. Подпись мешает изменить их, но не мешает прочитать. Если содержимое должно быть секретным, используйте JWE (зашифрованные токены).
Безопасно ли вставлять токен в онлайн-декодер?
Только если он работает локально. JWT Decoder от devpack декодирует данные в вашем браузере и ничего никуда не отправляет. Избегайте инструментов, которые передают токен на сервер, особенно рабочие токены.
Что означает «jwt malformed»?
Строка не состоит из трёх частей в Base64URL, разделённых точками. Обычно это значит, что перед токеном осталось «Bearer » или токен был обрезан при копировании.

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