[Документация Yandex Cloud](../index.md) > [Облачная терминология](index.md) > Безопасность > JSON Web Token (JWT)

# JSON Web Token (JWT)

_JSON Web Token_ — интернет-стандарт для безопасной передачи информации в виде ключей (токенов) в формате [JSON](https://ru.wikipedia.org/wiki/JSON). Благодаря компактности, безопасности и универсальности токен применяется повсеместно: от корпоративных систем до небольших сервисов и [интернета вещей](https://ru.wikipedia.org/wiki/Интернет_вещей).

В клиент-серверных приложениях JWT часто представлен в двух видах:

* **Access-токен** — подтверждает, что его владелец может воспользоваться защищенными ресурсами. Как правило, имеет непродолжительный срок жизни.
* **Refresh-токен** — используется для обмена на новый access-токен. Выдается на более длительный срок.

Для стандартизации создания токенов доступа в 2011 году была сформирована специальная группа разработчиков. К 2013 году в открытом доступе появились наработки группы, среди которых были несколько [видов](#types) токена, а также алгоритмы подписи, шифрования и управления ключами. В 2015 году JWT был официально закреплен в стандарте [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519).

## Типы JWT {#types}

В зависимости от назначения и структуры выделяют три основных типа JWT:

* JWS (JSON Web Signature) — токен с цифровой подписью для обеспечения целостности и аутентичности данных пользователя. Если данные не конфиденциальны, то этот токен предпочтительнее, потому что реализация и проверка подписи проходят быстрее.
* JWE (JSON Web Encryption) — зашифрованный токен для безопасной передачи данных. Используется в тех случаях, когда передаваемые в токене данные конфиденциальны, однако сложнее реализуется и дополнительно нагружает систему.
* Unsecured JWT — токен без подписи и шифрования. Такой токен легко подделать, поэтому он используется только в закрытых безопасных средах.

Сравним JWS и JWE подробнее:

Характеристика | JWS | JWE
---------------|-----|-----
Назначение | Обеспечение подлинности данных | Передача чувствительных данных
Читаемость полезной нагрузки | Читаемая | Зашифрованная
Сложность интеграции | Простая | Требует больше ресурсов и квалификации
Алгоритмы | [HMAC](https://ru.wikipedia.org/wiki/HMAC), [RSA](https://ru.wikipedia.org/wiki/RSA), [ECDSA](https://ru.wikipedia.org/wiki/ECDSA) | [AES](https://ru.wikipedia.org/wiki/AES_(стандарт_шифрования)), [RSA-OAEP](https://ru.wikipedia.org/wiki/Оптимальное_асимметричное_шифрование_с_дополнением), [ECDH-ES](https://ru.wikipedia.org/wiki/Протокол_Диффи_—_Хеллмана_на_эллиптических_кривых)
Производительность | Высокая | Средняя
Пример использования | Аутентификация в публичных API | Передача медицинских данных пациентов на сервер через публичную сеть

JWS и JWE также могут использоваться вместе (вложенный JWT), когда требуется и проверка аутентичности подписи, и шифрование [полезной нагрузки](#structure).

## Структура JWT {#structure}

Самый распространенный токен (JWS) состоит из трех компонентов:

* **Заголовок (header)** — передает информацию о типе токена и используемом криптографическом алгоритме.

  Пример:
  ```json
  {
  "alg": "HS256",
  "typ": "JWT"
  }
  ```
* **Полезная нагрузка (payload)** — передает содержащиеся в токене данные, называемые _утверждениями_. Утверждения делятся на три типа:

  * Стандартные — данные о токене, такие как предназначение, издатель, срок действия.
  * Пользовательские — данные пользователя токена, такие как имя, электронный адрес, номер телефона.
  * Нестандартные — специфические поля, необходимые для конкретных приложений. Например, роль пользователя.

  Пример:

  ```json
  {
    "sub": "user789",
    "name": "Ivan Ivanov",
    "iat": 1731000000,
    "exp": 1731003600,
    "email": "ivan-ivanov@example.com",
    "role": "developer"
  }
  ```

* **Подпись (signature)** — подтверждает, что токен подлинный и не был изменен. Создается на основе двух предыдущих зашифрованных компонентов, скомбинированных с секретным ключом. Для вычислений используется заданный в заголовке алгоритм. Сервер проверяет подпись, используя соответствующий ключ, чтобы убедиться, что токен не подделан.

В итоговом виде все компоненты токена кодируются в [Base64](https://ru.wikipedia.org/wiki/Base64) и отделяются друг от друга точками. Пример:

```text
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.бeyJzdWIiOiJ1c2VyNzg5IiwibmFtZSI6Ik
saWNlIFNtaXRoIiwicm9sZSI6ImVkaXRvciI
sImlhdCI6MTczMTAwMDAwMCwiZXhwIjoxNzM
xMDAzNjAwLCJlbWFpbCI6ImFsaWNlLnNtaXR
oQGV4YW1wbGU3kLHgqIm.6eE6f5rYvZ3f1Z5
f4q8v7m4k5n6p8r9s2t3u4vk********
```

## Безопасность JWT {#safety}

JWT — мощный инструмент для аутентификации, но имеет свои уязвимости и требует дополнительных усилий для обеспечения безопасности. Рассмотрим проблемы безопасности JWT и методы борьбы с ними:

* **Отзыв токена**. Механизм JWT не предполагает возможности быстро и эффективно отзывать токены — он рассчитан на то, что токен будет действителен до тех пор, пока не истечет его срок жизни. Поэтому, если у приложения есть необходимость отзывать токены раньше времени, то приходится использовать дополнительные меры. Например, хранить список отозванных токенов на сервере (черный список) и обращаться к нему при каждой попытке использования токена.

  Черный список аннулирует одно из основных преимуществ JWT — бессерверную архитектуру, поэтому для таких приложений практичнее воспользоваться [альтернативными](#jwt-vs-other-methods) средствами аутентификации. 

* **Некорректная проверка алгоритма шифрования**. Отсутствие алгоритма шифрования (`alg: "none"`) часто не делает токен невалидным. Если этим воспользуется злоумышленник, он сможет подделать токен без знания секретного ключа. Эту уязвимость пытаются устранить, однако по-прежнему находятся способы ею воспользоваться; предлагается даже убрать поле `alg` из заголовка.

  Для профилактики используйте только актуальные библиотеки, при проверке не полагайтесь на заголовок токена, а также явно указывайте ожидаемый алгоритм.

* **Подделка токена**. Если злоумышленник перехватит идентификационные данные пользователя, он сможет подделать токен и выдать себя за него.

  Для защиты можно нужно усложнять механизм проверки ключей, выпускаемых на основе токенов. Например, через использовани refresh-токенов.

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

  Рекомендуется изучить особенности алгоритмов и конфигураций токена, чтобы выбрать оптимальные для вашего приложения.

## Альтернативные методы аутентификации {#jwt-vs-other-methods}

### Сравнение JWT с учетными данными {#credentials}

Вместо использования JWT можно аутентифицироваться с помощью ввода учетных данных (credentials), однако токен имеет ряд преимуществ:

| Характеристика | JWT | Credentials |
|----------------|-----|-------------|
| **Шифрование** | Поддерживается по умолчанию | Требуется подключение дополнительных механизмов |
| **Срок действия** | Небольшой: снижается вероятность несанкционированного доступа при утечке токена | Длительный: повышается время для утечки и алгоритмов расшифровки |
| **Самодостаточность** | Хранит в себе всю требующуюся информацию | Для валидации обращается к базе данных, а это медленнее и дороже |
| **Масштабирование** | Простое за счет бессерверной архитектуры | Усложнено синхронизацией состояния между серверами |
| **Поддержка** | Поддерживается всеми актуальными стандартами и протоколами | Ограничена политиками [CORS](cors.md) |
| **Гибкость** | Поддерживает передачу дополнительных данных, например, роль и права доступа | Обычно ограничены логином и паролем |

Когда использование учетных данных предпочтительнее:

* Для небольших приложений с минимальными требованиями к масштабированию сессионные cookie проще в реализации, чем JWT.
* Если приложение предполагает краткосрочную сессию, завершающуюся после выхода пользователя, практичнее будет использовать учетные данные. По завершении сессии токен сложнее отозвать — придется добавлять его в черный список.
* Для старых систем, где аутентификация с помощью учетных данных уже настроена и защищена, переход на JWT обычно неоправдан.

### Сравнение JWT c PASETO {#paseto}

Наиболее близкая альтернатива JWT — [PASETO](https://paseto.io/). Токен создан как более простой и безопасный аналог, однако сейчас он не поддерживается многими языками программирования, библиотеками и фреймворками. Сравним токены подробнее:

| Характеристика | JWT | PASETO |
|----------------|-----|--------|
| **Гибкость** | Более гибкий, но требует сложной настройки и выбора алгоритма | Выбор настроек и алгоритмов меньше, но вероятность ошибки разработчика снижена |
| **Выбор алгоритма** | Выбирается разработчиком, передается в заголовке. Метод [уязвим](#safety) для атак | Заранее определен версией токена, нельзя изменить или отменить |
| **Конфиденциальность** | Опциональна, требует сложной реализации через [JWE](#types) | Встроенная поддержка через [AEAD](https://ru.wikipedia.org/wiki/AEAD-режим_блочного_шифрования), простая реализация |
| **Размер токена** | От 128 до 512 бит (возможны исключения) | От 384 до 512 бит |
| **Производительность** | Зависит от алгоритмов, в среднем ниже | В среднем выше, но разница заметна только при большом количестве операций |
| **Досрочный отзыв токена** | Вручную | Через систему контроля версий |
| **Поддержка** | Широкая | [Ограниченная](https://paseto.io/) |

По большинству критериев PASETO совершеннее своего конкурента, однако есть ряд случаев, когда выбор JWT предпочтительнее:

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

## JWT в Yandex Cloud {#jwt-yc}

В Yandex Cloud доступен сервис [Yandex Identity and Access Management](../iam/index.md), который обеспечивает централизованное управление ресурсами с помощью разных методов. Рассмотрим основные методы аутентификации с использованием JWT:

* [ID-токен](../iam/concepts/authorization/id-token.md) — JWT, который используется для аутентификации сервисного аккаунта в сторонней системе.
* [IAM-токен](../iam/concepts/authorization/iam-token.md) — токен для доступа к внутренним ресурсам облака, который можно получить путем обмена на JWT.

Подробнее о методах аутентификации в Identity and Access Management в [документации](../iam/concepts/authorization/index.md).