JSON веб-токен (JWT)

JSON веб-токен (JWT)

JSON веб-токен (JWT) — это строка, представляющая набор параметров в формате объекта JSON, который закодирован в виде структуры JWS (JSON Web Signature) или JWE (JSON Web Encryption). При этом параметры объекта JSON сопровождаются цифровой подписью, кодом аутентификации и/или шифрованием.

Назначение

JSON веб-токен (JWT) — это открытый стандарт (RFC 7519), разработанный для безопасной передачи данных между сторонами в компактном и самодостаточном формате. Он используется для:

  • Аутентификации: Подтверждения личности пользователя, например, в протоколе OpenID Connect через ID токены.
  • Авторизации: Предоставления доступа к защищенным ресурсам в OAuth 2.0 через токены доступа.
  • Обмена информацией: Безопасной передачи данных между системами с гарантией целостности и подлинности.
  • Единого входа (SSO): Упрощения аутентификации в нескольких приложениях или доменах.

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

История

Разработка JWT началась в 2011 году в рамках группы JOSE (JSON Object Signing and Encryption), созданной для стандартизации механизмов защиты данных в формате JSON. К 2013 году появились черновики стандартов JWT, JWS (JSON Web Signature), JWE (JSON Web Encryption), JWK (JSON Web Key) и JWA (JSON Web Algorithms). Официально стандарт JWT был опубликован в мае 2015 года группой IETF (RFC 7519).

Структура

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

  1. Заголовок (Header):
    • Содержит метаданные о токене, включая:
      • typ: Тип токена, обычно «JWT».
      • alg: Алгоритм подписи, например, HS256 (HMAC SHA-256), RS256 (RSA SHA-256) или none (без подписи).
  2. Полезная нагрузка (Payload):
    • Содержит утверждения (claims) — данные о пользователе, токене или другие параметры. Утверждения делятся на:
      • Зарегистрированные (Registered claims): Стандартные, необязательные ключи, такие как:
        • iss (issuer): Идентификатор издателя токена.
        • sub (subject): Идентификатор субъекта (например, пользователя).
        • aud (audience): Получатель токена.
        • exp (expiration): Время истечения срока действия (Unix Time).
        • nbf (not before): Время, с которого токен действителен.
        • iat (issued at): Время выдачи токена.
        • jti (JWT ID): Уникальный идентификатор токена.
      • Публичные (Public claims): Определяются в реестре IANA или как URI для избежания коллизий.
      • Частные (Private claims): Пользовательские данные, согласованные между сторонами, например, name или admin.
  3. Подпись (Signature):
    • Создается путем объединения закодированных заголовка и полезной нагрузки, подписанных с использованием секрета или закрытого ключа по алгоритму, указанному в заголовке.

Как работает

JWT используется в клиент-серверных приложениях следующим образом:

  1. Аутентификация: Клиент (например, веб-приложение) аутентифицируется на сервере авторизации, предоставляя учетные данные, такие как логин и пароль.
  2. Выдача токенов: Сервер авторизации генерирует JWT (обычно access-токен и refresh-токен), подписывает его и отправляет клиенту.
  3. Использование access-токена: Клиент включает access-токен в заголовок HTTP-запроса (Authorization: Bearer <token>) для доступа к защищенным ресурсам.
  4. Проверка токена: Сервер ресурсов (например, API) проверяет подпись токена, его срок действия и утверждения, чтобы разрешить или отклонить запрос.
  5. Обновление токена: При истечении срока действия access-токена клиент использует refresh-токен для получения нового access-токена от сервера авторизации.
  6. Повторная аутентификация: Если refresh-токен истекает или отзывается, клиент должен пройти аутентификацию заново.

JWT поддерживает два типа токенов:

  • Access-токен: Короткоживущий токен (например, 1 час), используемый для доступа к ресурсам. Может содержать scopes, определяющие разрешенные операции.
  • Refresh-токен: Долгоживущий токен (например, месяц или год), используемый для обновления access-токена без повторной аутентификации.

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

JWT обладает рядом преимуществ по сравнению с другими стандартами, такими как SAML или SWT:

  • Компактность: Меньший размер по сравнению с XML-базированными стандартами, что упрощает передачу в HTTP-запросах.
  • Простота обработки: JSON легко парсится в большинстве языков программирования, в отличие от XML.
  • Без хранения сессий: Серверу не нужно хранить данные о сессиях, так как вся информация содержится в токене, что упрощает масштабирование.
  • Кросс-доменная поддержка: Подходит для единого входа (SSO) и работы с несколькими сервисами.
  • Гибкость подписи: Поддерживает симметричную (HMAC) и асимметричную (RSA, ECDSA) подпись, обеспечивая выбор между скоростью и безопасностью.

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

JWT обеспечивает безопасность благодаря подписи и шифрованию, но требует соблюдения следующих мер:

  • Передача по HTTPS: Все запросы с JWT должны использовать HTTPS для защиты от перехвата (JWT Best Practices).
  • Валидация и верификация: Проверка подписи, утверждений (iss, aud, exp) и срока действия токена для предотвращения подделки.
  • Короткий срок действия: Access-токены должны иметь ограниченный срок жизни (например, 1 час) для минимизации риска при утечке.
  • Безопасное хранение: Токены не должны храниться в незащищенных местах, таких как DOM-хранилище браузера. Рекомендуется использовать cookie с флагом HttpOnly для защиты от XSS-атак.

Возможные уязвимости:

  • Удаление подписи: Злоумышленник может удалить подпись и изменить заголовок, указав alg: none. Решение: Отбрасывать неподписанные токены (JWT Security).
  • CSRF: Если JWT передается не в cookie, а в заголовке, атака CSRF невозможна. При использовании cookie требуется защита, например, CSRF-токены.
  • XSS: Хранение JWT в DOM-хранилище уязвимо к XSS-атакам. Решение: Использовать cookie с флагом HttpOnly (JWT Storage).
  • Переполнение заголовков: Слишком большие JWT могут превысить лимиты HTTP-заголовков (например, 8 КБ). Решение: Ограничивать объем данных в токене.

Применение

JWT используется в следующих сценариях:

  • Авторизация: В OAuth 2.0 для предоставления доступа к защищенным ресурсам через access-токены.
  • Аутентификация: В OpenID Connect как ID токен для подтверждения личности пользователя.
  • Обмен информацией: Для безопасной передачи данных между системами, например, между микросервисами.
  • Единый вход (SSO): Для аутентификации через сторонние провайдеры идентификации, упрощая доступ к нескольким приложениям.

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

Значение в современных системах

JWT — это универсальный и широко распространенный стандарт для аутентификации и авторизации в современных веб-приложениях. Его компактность, поддержка подписи и шифрования, а также совместимость с различными платформами делают его идеальным для распределенных систем, микросервисов и кросс-доменных приложений. В сочетании с OAuth 2.0 и OpenID Connect JWT обеспечивает безопасное и удобное управление доступом, что делает его незаменимым в цифровой экосистеме.