Открыть сервис

JWT-токен

JWT-токен (JSON Web Token, RFC 7519) — это компактный, URL-безопасный формат представления данных в виде JSON-объекта, используемый для передачи информации между двумя сторонами. JWT-токен чаще всего применяется в системах аутентификации и авторизации, а также для безопасного обмена данными в веб-приложениях и API. Токен подписывается цифровой подписью или шифруется, что позволяет проверять его целостность и подлинность.

Структура JWT-токена

JWT-токен состоит из трёх частей, разделённых точками (.):

`` header.payload.signature ``

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

Заголовок содержит метаданные о токене: тип токена (обычно JWT) и алгоритм подписи или шифрования (например, HS256, RS256). Пример:

``json { "alg": "HS256", "typ": "JWT" } ``

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

Полезная нагрузка содержит утверждения (claims) — пары «ключ-значение», описывающие сущность (например, пользователя) и дополнительные данные. Утверждения делятся на три типа:

  • Зарегистрированные — стандартные поля, определённые в RFC 7519: iss (издатель), sub (субъект), aud (аудитория), exp (срок действия), nbf (не ранее), iat (время выдачи), jti (уникальный идентификатор).
  • Публичные — произвольные имена, определённые разработчиком, но регистрируемые в реестре IANA (например, name, email).
  • Частные — произвольные пары, согласованные между сторонами (например, role: "admin").

Пример payload:

``json { "sub": "1234567890", "name": "Иван Иванов", "iat": 1516239022, "exp": 1516242622 } ``

Signature (подпись)

Подпись создаётся путём объединения закодированного заголовка, закодированной полезной нагрузки и секретного ключа (или пары ключей) с использованием указанного алгоритма. Подпись позволяет проверить, что токен не был изменён после создания. Для симметричного алгоритма (HS256) используется общий секрет; для асимметричного (RS256) — закрытый ключ для подписи и открытый для проверки.

Принцип работы

  1. Создание токена: сервер аутентификации генерирует JWT, подписывая заголовок и payload секретным ключом.
  2. Передача токена: токен передаётся клиенту (например, в HTTP-заголовке Authorization: Bearer <token>).
  3. Проверка токена: клиент отправляет токен серверу при каждом запросе. Сервер проверяет подпись, срок действия и другие утверждения. Если всё корректно, сервер доверяет данным в payload.

JWT-токен является самодостаточным: вся необходимая информация для проверки и авторизации содержится в самом токене, что снижает нагрузку на базу данных.

Классификация JWT-токенов по типу подписи

JWS (JSON Web Signature)

Наиболее распространённый тип — токен подписывается, но не шифруется. Данные в payload читаемы (base64url-кодированы), но не могут быть изменены без нарушения подписи. Используется для аутентификации и авторизации.

JWE (JSON Web Encryption)

Токен шифруется, что обеспечивает конфиденциальность данных. Payload недоступен для чтения без ключа расшифровки. Применяется для передачи чувствительной информации.

Применение JWT-токенов

Аутентификация и авторизация

JWT-токены широко используются в REST API и микросервисных архитектурах. После успешного входа сервер выдаёт токен, который клиент (браузер, мобильное приложение) отправляет с каждым запросом. Сервер проверяет токен без обращения к базе данных, что повышает производительность.

Обмен данными между сервисами

В распределённых системах JWT-токены позволяют безопасно передавать утверждения между сервисами. Например, сервис аутентификации может выдать токен, который затем используется другими сервисами для авторизации.

Single Sign-On (SSO)

JWT-токены часто используются в системах единого входа (SSO), где один токен предоставляет доступ к нескольким приложениям.

Восстановление пароля и подтверждение email

JWT-токены могут использоваться для создания одноразовых ссылок, содержащих информацию о пользователе и сроке действия.

Преимущества и недостатки

Преимущества

  • Компактность: токен имеет небольшой размер, что удобно для передачи в HTTP-заголовках и URL.
  • Самодостаточность: все данные для проверки содержатся в токене, не требуется обращение к базе данных.
  • Кроссплатформенность: JWT-токены поддерживаются большинством языков программирования и платформ.
  • Безопасность: подпись гарантирует целостность, а шифрование — конфиденциальность.

Недостатки

  • Неотзываемость: после выдачи токен действителен до истечения срока (exp). Отзыв токена до истечения срока требует дополнительных механизмов (например, чёрный список).
  • Размер: payload может быть большим, что увеличивает объём передаваемых данных.
  • Хранение на клиенте: токен должен храниться безопасно (например, в httpOnly cookie или secure storage), чтобы избежать XSS-атак.
  • Сложность управления ключами: при использовании асимметричных алгоритмов требуется безопасное хранение закрытых ключей.

Безопасность и уязвимости

Основные угрозы

  • Кража токена: если злоумышленник получит токен (например, через XSS или перехват трафика), он сможет действовать от имени пользователя. Для защиты используются HTTPS, httpOnly cookies и короткие сроки жизни токенов.
  • Атака с подделкой подписи: если секретный ключ скомпрометирован, злоумышленник может создавать поддельные токены.
  • Атака с изменением алгоритма: если сервер не проверяет алгоритм подписи, злоумышленник может изменить alg на none и обойти проверку. Для защиты сервер должен явно указывать допустимые алгоритмы.

Рекомендации по безопасному использованию

  • Использовать HTTPS для всех запросов.
  • Устанавливать короткие сроки действия токенов (например, 15–30 минут).
  • Использовать refresh-токены для продления сессии без повторного ввода пароля.
  • Хранить токены в httpOnly cookies или secure storage (не в localStorage).
  • Проверять алгоритм подписи на стороне сервера.
  • Использовать асимметричные алгоритмы (RS256, ES256) для распределённых систем.

Примеры реализации

Создание JWT-токена на сервере (Node.js с библиотекой jsonwebtoken)

``javascript const jwt = require('jsonwebtoken'); const token = jwt.sign( { userId: 123, role: 'admin' }, 'secret_key', { expiresIn: '1h' } ); ``

Проверка JWT-токена на сервере

``javascript try { const decoded = jwt.verify(token, 'secret_key'); console.log(decoded.userId); } catch (err) { console.error('Token invalid'); } ``

Интересные факты

  • JWT-токены были стандартизированы IETF в 2015 году (RFC 7519).
  • Формат JWT-токена основан на JSON, что делает его удобным для веб-приложений.
  • JWT-токены часто используются в связке с OAuth 2.0 и OpenID Connect.
  • Существует множество библиотек для работы с JWT на всех популярных языках программирования.

Источники

  • RFC 7519 — JSON Web Token (JWT)
  • RFC 7515 — JSON Web Signature (JWS)
  • RFC 7516 — JSON Web Encryption (JWE)
  • Документация библиотеки jsonwebtoken (Node.js)
  • Статья «JWT Authentication: Best Practices» на Auth0
  • Материалы курса «Web Security» от OWASP

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →