JWT: как прочитать токен

↑ 1.3 Аутентификация и безопасность API · ← Предыдущая · → Следующая

Обязательно~5 мин чтенияУровень: junior

Зачем это аналитику и 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 роль из токена или берёт права из базы. Если это неизвестно, стоит вопрос, не догадка.

Вопросы с ответами

Связано с блоком Developer

Связанные темы