05 jwt

Многие API и системы авторизации отдают токен в виде JWT — компактной строки, в которой в закодированном виде хранятся данные (например, кто пользователь и какие у него права) и подпись для проверки подлинности. В этом файле разберём, что такое JWT, из чего он состоит, как его проверяют и как использовать в Postman и в запросах к API.


1. Что такое JWT и зачем он нужен

JWT (JSON Web Token) — это стандартный способ представить утверждения (claims) в виде компактной строки. Утверждения — это пары «ключ–значение»: например, идентификатор пользователя, роль, срок действия токена. Строка состоит из трёх частей в формате Base64URL, разделённых точками: header.payload.signature.

Зачем JWT нужен в API:

  • Без состояния (stateless) — серверу не обязательно хранить сессию. Достаточно проверить подпись токена и прочитать данные из него.

  • Один токен — и для идентификации, и для прав — в payload можно передать sub (кто), roles, exp (до какого времени действует) и т.д.

  • Удобно для микросервисов и нескольких серверов — любой сервис с секретным ключом (или публичным ключом при асимметричной подписи) может проверить токен без обращения к общему хранилищу сессий.

JWT часто выступает в роли access token в OAuth 2.0: после входа пользователь или клиент получает JWT и передаёт его в заголовке Authorization: Bearer <token> при каждом запросе к API.


2. Структура JWT: header, payload, signature

JWT — это строка из трёх частей, разделённых точкой:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4iLCJleHAiOjE2MTYyMzkwMjJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Условно: header.payload.signature.

Header (заголовок)

Первая часть — Base64URL-кодированный JSON с метаданными токена. Обычно там указывают алгоритм подписи и тип токена.

Пример (до кодирования):

  • alg — алгоритм подписи (например, HS256, RS256).

  • typ — тип токена, как правило JWT.

Payload (полезная нагрузка)

Вторая часть — Base64URL-кодированный JSON с утверждениями (claims). Стандартные поля (названия зарезервированы):

Поле
Название
Описание

sub

Subject

Кто субъект (часто ID пользователя).

iss

Issuer

Кто выдал токен (URL или имя сервиса).

aud

Audience

Для кого предназначен токен.

exp

Expiration

Время истечения (Unix timestamp).

iat

Issued At

Время выдачи (Unix timestamp).

Можно добавлять свои поля: role, email, userId и т.д. Всё, что лежит в payload, не шифруется — только кодируется в Base64, поэтому в JWT не кладут пароли и секреты.

Пример payload (до кодирования):

Signature (подпись)

Третья часть — подпись, вычисленная по алгоритму из header над строкой header.payload. Секрет (при HS256) или приватный ключ (при RS256) знает только тот, кто выдаёт токен. Сервер проверяет: пересчитать подпись с тем же секретом/ключом и сравнить с той, что в токене. Если совпадает — токен не меняли и он был выдан нашим сервером.

Итог: JWT = закодированный header + закодированный payload + подпись. Данные в payload можно прочитать без секрета (Base64 декодируется), но подделать токен без знания секрета или приватного ключа нельзя.


3. Как работает подпись и проверка

  1. Выдача токена: сервер авторизации формирует header и payload, кодирует их в Base64URL, вычисляет подпись (например, HMAC-SHA256 от строки base64(header).base64(payload) с секретным ключом) и склеивает три части точками.

  2. Передача: клиент получает JWT (через ответ на логин, через OAuth 2.0 и т.д.) и сохраняет его.

  3. Запрос к API: клиент отправляет запрос с заголовком Authorization: Bearer <JWT>.

  4. Проверка: API-сервер берёт JWT, снова вычисляет подпись с тем же секретом (или проверяет подпись публичным ключом при RS256). Если подпись совпадает и exp ещё не истёк — токен считается действительным; данные из payload (например, sub, role) используются для авторизации.

Если кто-то изменит payload (например, подставит другого пользователя), подпись перестанет сходиться и сервер отклонит токен.


4. Где используется JWT

  • Access token в OAuth 2.0 — многие провайдеры (и корпоративные IdP) отдают access token в формате JWT. В Postman вы получаете его через OAuth 2.0 и отправляете как Bearer — под капотом это может быть JWT.

  • Собственный API после логина — пользователь логинится (логин/пароль или OAuth), сервер выдаёт JWT с sub, exp, ролями; клиент при каждом запросе передаёт этот JWT в заголовке.

  • Обмен между сервисами — один микросервис получает JWT от шлюза или IdP и передаёт его дальше (или формирует свой JWT с утверждениями для другого сервиса).

  • Single Sign-On (SSO) — после входа в корпоративный портал пользователь получает JWT и с ним заходит в разные приложения без повторного ввода пароля.

В методичке важно понимать: если в ответе на логин или в OAuth вы видите длинную строку из трёх частей, разделённых точками, — это скорее всего JWT. Её и нужно передавать в Authorization: Bearer <token>.


5. Работа с JWT в Postman

С точки зрения Postman JWT — это обычный Bearer Token. Не важно, выдал ли его ваш login endpoint или OAuth 2.0: способ передачи один и тот же.

Вариант 1: токен приходит в ответе на логин

Если у вас есть endpoint вида POST /auth/login (тело: логин/пароль), и в ответе приходит JSON с полем access_token или token (часто это JWT):

  1. Создайте запрос POST на ваш login URL, в Body передайте учётные данные.

  2. Отправьте запрос, в ответе скопируйте значение access_token (или как оно названо в API).

  3. В запросе к защищённому API откройте вкладку Authorization → Type: Bearer Token → вставьте скопированный токен.

Либо настройте в коллекции Pre-request Script или отдельный запрос «логин», который сохраняет токен в переменную окружения, а в остальных запросах используйте Authorization → Bearer Token → значение {{access_token}} (см. документацию Postman по переменным и скриптам).

Вариант 2: токен приходит через OAuth 2.0

Как в файле про OAuth 2.0 в Postman: вы настраиваете OAuth 2.0, нажимаете Get New Access Token, получаете токен. Если провайдер отдаёт JWT, Postman просто подставляет его в заголовок — отдельно указывать, что это JWT, не нужно.

Вариант 3: токен выдан вручную (для тестов)

Если токен вам выдали отдельно (например, для доступа к тестовому окружению):

  1. Authorization → Type: Bearer Token.

  2. В поле токена вставьте полную строку JWT (все три части с точками).

  3. Отправляйте запрос — заголовок Authorization: Bearer <ваш_jwt> уйдёт на сервер.

Практика: если у вас есть любой JWT (от вашего API или от учебного сервиса), вставьте его в Postman как Bearer Token и выполните запрос к защищённому endpoint. Затем расшифруйте payload на jwt.ioarrow-up-right (см. следующий раздел).


6. Расшифровка и отладка

Данные в JWT не зашифрованы, только закодированы в Base64. Любой может скопировать токен и прочитать header и payload (но не подделать без секрета). Для отладки удобно использовать:

  • jwt.io — вставьте строку JWT в поле «Encoded»; в блоке «Decoded» отобразятся header и payload в читаемом виде. Проверка подписи на сайте возможна только если вы знаете секрет и введёте его (для своих токенов в учебных целях), иначе просто смотрите содержимое.

По payload можно проверить:

  • exp — не истёк ли токен;

  • sub, email, role — от имени кого и с какими правами идёт запрос.

Если API возвращает 401, первым делом стоит проверить: токен передан в заголовке Authorization: Bearer ..., не истёк ли срок по exp и не обрезана ли строка при копировании.


7. Практическая часть: генерация и декодирование JWT

Ниже — два способа самостоятельно поработать с JWT: на официальном сайте jwt.io (без кода) и с помощью PHP (генерация и декодирование в коде). Выполните оба варианта, чтобы закрепить понимание структуры токена.

7.1. Декодирование и генерация на jwt.io

Сайт jwt.ioarrow-up-right — официальный отладчик JWT от Auth0. Он позволяет и декодировать готовый токен, и сгенерировать новый (с подписью или без).

Задание 1: Декодировать готовый JWT

  1. Откройте jwt.ioarrow-up-right.

  2. В блоке Encoded уже подставлен пример токена. Удалите его и вставьте любой свой JWT (например, из ответа вашего API или OAuth, или этот учебный):

  3. Справа в блоке Decoded появятся:

    • HEADER — алгоритм и тип;

    • PAYLOAD — все утверждения (sub, name, role, exp, iat и т.д.).

  4. Обратите внимание на exp — это Unix timestamp. Переведите его в дату (например, на unixtimestamp.comarrow-up-right) и проверьте, истёк ли токен.

Практика: возьмите токен из Postman (после OAuth с GitHub или из ответа на логин) и вставьте на jwt.io. Запишите, какие поля есть в payload и какое значение у exp.

Задание 2: Сгенерировать свой JWT на jwt.io

  1. На jwt.ioarrow-up-right перейдите к блоку Decoded.

  2. В PAYLOAD измените JSON на свой. Например:

    Значение exp задайте в будущем: текущее время в секундах + 3600 (час). Узнать текущий timestamp можно, например, выполнив в консоли браузера Math.floor(Date.now() / 1000).

  3. Внизу страницы в поле Verify Signature введите секрет (любую строку для учебного примера), например: my-secret-key.

  4. Алгоритм оставьте HS256. Строка в блоке Encoded обновится автоматически — это ваш подписанный JWT.

  5. Скопируйте получившийся токен из Encoded и снова вставьте его в поле Encoded (можно очистить и вставить заново). Убедитесь, что в Decoded отображаются ваши данные и подпись отображается как «Signature Verified», если секрет совпадает.

Практика: сгенерируйте токен с полями sub, name, role, exp, скопируйте его и подставьте в Postman как Bearer Token в запросе к любому вашему API (если он проверяет JWT с тем же секретом — запрос пройдёт; для стороннего API достаточно убедиться, что заголовок уходит корректно).


7.2. Генерация и декодирование JWT в PHP

Если у вас установлен PHP (8.0+), можно сгенерировать и декодировать JWT в коде. Удобно использовать библиотеку firebase/php-jwt.

Установка

В каталоге проекта выполните (нужен Composer):

Декодирование JWT (без проверки подписи — только для учёбы)

Для начала можно просто прочитать payload, чтобы увидеть структуру (в реальном коде подпись нужно проверять):

Сохраните скрипт как decode_jwt.php, подставьте свой JWT (например, сгенерированный на jwt.io с секретом my-secret-key) и запустите: php decode_jwt.php. В выводе будут все поля payload.

Если нужно только прочитать payload без проверки подписи (например, для отладки чужого токена), можно распарсить только среднюю часть:

Здесь подпись не проверяется — используйте только для учебных токенов.

Генерация JWT в PHP

Пример: сформировать токен с payload и подписать его секретом (HS256):

Сохраните как create_jwt.php и выполните: php create_jwt.php. Скопируйте выведенный JWT и вставьте его на jwt.io — payload и подпись должны совпасть при том же секрете.

Практика: измените в create_jwt.php поля sub, name, role и время exp. Запустите скрипт, подставьте полученный JWT в Postman как Bearer Token и (если у вас есть свой API с тем же секретом) выполните запрос.


Краткое резюме практики

Действие
jwt.io
PHP

Декодировать токен (прочитать payload)

Вставить в Encoded, смотреть Decoded

JWT::decode() с Key или разбор средней части через base64_decode

Сгенерировать токен с подписью

Редактировать Payload, ввести секрет в Verify Signature

JWT::encode($payload, $secret, 'HS256')

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


8. Безопасность

  • Не храните секреты в payload — payload только кодируется в Base64, его легко прочитать. Пароли, ключи, номера карт в JWT не кладут.

  • Передавайте токен только по HTTPS — иначе токен можно перехватить и использовать до истечения срока.

  • Короткий срок жизни access token — типично минуты или часы. Для продления используют refresh token или повторный логин.

  • Храните JWT у клиента аккуратно — в браузере предпочтительно память или httpOnly cookie, не localStorage, если есть риск XSS. В мобильном приложении и в Postman — как предписано политикой безопасности вашей компании.

  • Алгоритм подписи — сервер должен проверять подпись и не принимать токены с отключённой проверкой (alg: none) и устаревшими алгоритмами при необходимости.

Эти принципы помогут и при использовании API компании, и при проектировании собственных сервисов.


9. Что дальше

Вы разобрались с тем, что такое JWT, из чего он состоит (header, payload, signature), как его проверяют и как передавать в Postman как Bearer Token. Дальше в методичке — итоговое практическое задание: работа с API Бизнес.Ру (OAuth 2.0 через Бизнес.ID, создание и изменение контрагентов и заказов в Postman или в коде). См. Итоговое задание: API Бизнес.Ру.