JWT: как прочитать токен
↑ 1.3 Аутентификация и безопасность API · ← Предыдущая · → Следующая
Зачем это аналитику и PM
В токене часто лежат срок, субъект и роль, из-за которых метод отвечает отказом. Полезную нагрузку можно прочитать глазами, но подпись и секрет подписи трогать нельзя, а чужой боевой токен в тикет не кладут.
План темы
- header, payload, signature
- claims
- срок жизни
- что можно, а чего нельзя хранить в токене
Объяснение
JWT (JSON Web Token) — строка из трёх частей, которой часто пользуются как Bearer-токеном. Части разделены точками: заголовок, полезная нагрузка и подпись. Первые две — это JSON в кодировке Base64url. Их видно без ключа. Подпись нужна, чтобы получатель проверил, что байты не переписали.
Как прозрачный конверт с сургучом. Текст приказа читает каждый, кто взял конверт. Сургуч показывает, что приказ не подменили по дороге. Снять сургуч и пририсовать себе роль «администратор» нельзя: проверка на сервере не сойдётся. Конверт при этом не сейф. Всё, что написано внутри, секретом не является.
Три части
Заголовок говорит, как устроена подпись. Поле alg — алгоритм, typ часто равен JWT. Полезная нагрузка — утверждения, claims: кто субъект, когда токен кончается и что ещё решил положить издатель. Подпись считают от первых двух частей секретом или ключом. Без проверки подписи токену верят зря: JSON легко собрать заново.
Срок смотрят в claim exp. Это момент времени числом, обычно секунды Unix, не «через час» словами. Имена стандартные, но набор в вашем токене подтверждает издатель. Роль в токене бывает, а бывает только идентификатор субъекта, а права сервер берёт из своей базы. Не обещайте экран «роль из токена», пока это не сказано в контракте.
Что класть внутрь
Можно класть то, что не стыдно показать обладателю токена и любому, кто его перехватит в журнале: идентификатор, имя роли, срок. Нельзя класть пароль, секрет клиента, полный паспортный номер и лишние персональные данные «чтобы экран не ходил в API». Токен копируют в отладку, в ошибки, в заголовки прокси. Подпись не прячет текст.
Алгоритм none в заголовке — известная ловушка старых проверок: подписи как будто нет. В требованиях его не выбирают. Если такой токен где-то ещё принимают, это дефект проверки, не формат для новых задач.
Примеры
Ниже вымышленный токен. Подпись — метка example-signature-not-valid, она не сойдётся ни на одном боевом ключе. Строку не отправляют на настоящий API и не принимают за чей-то допуск.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLWV4YW1wbGUiLCJuYW1lIjoiRXhhbXBsZSBVc2VyIiwicm9sZSI6ImFuYWx5c3QiLCJleHAiOjE4OTM0NTYwMDB9.example-signature-not-validЕсли раскодировать первые две части как Base64url, получатся такие JSON. Число exp тоже учебное.
{
"alg": "HS256",
"typ": "JWT"
}{
"sub": "user-example",
"name": "Example User",
"role": "analyst",
"exp": 1893456000
}GET /orders HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJ...Нюансы и подводные камни
- Прочитать payload ещё не значит, что токен принят сервером. Нужны подпись, срок и совпадение издателя.
- Часы на машине и
expрасходятся. Отказ «токен протух» иногда лечится сверкой времени, не сменой роли. - Декодируйте только свои тестовые токены или явно учебные строки. Чужой токен из тикета — уже утечка.
Практика
Возьмите учебную строку из этой темы или тестовый токен своего стенда. Разделите её по точкам и выпишите sub и exp, не копируя подпись в отчёт.
Ожидаемый результат: две части распознаны как JSON, третья помечена как подпись и в отчёт не вставлена целиком. Рядом фраза, проверяет ли ваш API роль из токена или берёт права из базы. Если это неизвестно, стоит вопрос, не догадка.
Вопросы с ответами
JWT зашифрован?
Обычно нет. Заголовок и нагрузка только закодированы, их читают без ключа. Подпись подтверждает целостность. Шифрование — отдельная история и в обычном access token его не предполагают.
Можно ли поправить роль в середине строки?
Текст поправить можно, проверку подписи это сломает. Сервер с нормальной проверкой такой токен отвергнет. Отключённая проверка подписи — дефект, не приём работы.
Где написан срок?
В claim
exp, если издатель его поставил. Это число, момент времени. Истёкший токен не лечат повторной отправкой того же заголовка.
Что нельзя класть в payload?
Пароли, секреты и лишние персональные данные. Всё, что внутри, видно любому, у кого оказалась строка токена.