JWT (JSON Web Tokens)

JWT (англ. JSON Web Token, также JSON-веб-токен) — открытый стандарт RFC 7519, задающий компактный и самодостаточный способ безопасной передачи данных между сторонами в формате JSON[1]. Подлинность токена подтверждается за счёт цифровой подписи, что обеспечивает целостность передаваемой информации[2].

Общие сведения
JWT
англ. JSON Web Token
Область использования Веб-разработка, Информационная безопасность

История

Разработка стандарта JWT велась в рамках Инженерного совета Интернета (IETF) при участии рабочей группы JOSE (JSON Object Signing and Encryption), сформированной в 2011 году для создания стандартов подписи и шифрования JSON-объектов. Предпосылкой стало появление формата JSON, разработанного в 2000-х годах Дугласом Крокфордом как более простая альтернатива XML. Первые черновики спецификаций JOSE начали публиковаться к 2013 году. В мае 2015 года был утверждён стандарт RFC 7519 (JSON Web Token), авторами которого стали Майкл Б. Джонс, Джон Брэдли и Нэт Сакимура. Одновременно были приняты связанные спецификации: RFC 7515 (JWS, цифровая подпись), RFC 7516 (JWE, шифрование), RFC 7517 (JWK, представление ключей) и RFC 7518 (JWA, алгоритмы). В настоящее время JWT остаётся промышленным стандартом для безопасной передачи данных между сторонами[3][4][4][5][6].

Определение

Согласно RFC 7519, JSON Web Token — это компактное URL-безопасное средство представления утверждений (claims) для передачи между сторонами. Токен представляет собой строку из трёх частей (заголовок, полезная нагрузка и подпись), разделённых точками и закодированных с использованием Base64URL[1].

Основные свойства:

  • Компактность: использование JSON и Base64URL-кодирования позволяет передавать токен в HTTP-заголовках и URL[7].
  • Самодостаточность: все необходимые данные о субъекте содержатся внутри токена, что исключает необходимость хранения состояния сессии на сервере.
  • Проверяемость и криптографическая защита: подпись (или MAC), создаваемая с использованием HMAC, RSA или ECDSA, гарантирует целостность данных и подлинность издателя[2].
  • Расширяемость: наряду с зарегистрированными клеймами (iss, exp, sub, aud и др.) допускается использование пользовательских данных[8].
  • Открытость стандарта: спецификация RFC 7519 свободно реализуется в различных языках и средах[9].

Структурные элементы JWT

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

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

JSON-объект с метаданными токена. Основные поля:

  • typ — тип токена, обычно «JWT»;
  • alg — алгоритм подписи (например, HS256, RS256) либо значение «none» для неподписанных токенов. Возможность указания «none» является известной уязвимостью (атака с подменой алгоритма): злоумышленник может изменить это поле на «none» и удалить подпись. Если серверная библиотека сконфигурирована неверно и не проверяет алгоритм, она может посчитать такой токен действительным, что позволяет полностью подделать его содержимое[10].

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

Содержит совокупность утверждений (claims), которые делятся на зарегистрированные, публичные и частные.

  • Зарегистрированные утверждения (Registered Claims): предопределённый набор утверждений, таких как iss (издатель), exp (срок действия), sub (субъект), aud (аудитория), nbf (не раньше), iat (создан) и jti (идентификатор токена).
  • Публичные и частные утверждения (Public and Private Claims): пользовательские данные (например, role, userId).

Поскольку полезная нагрузка по умолчанию не шифруется, а лишь кодируется с помощью Base64url, её содержимое может быть легко прочитано любой стороной, перехватившей токен. Это создаёт риск утечки чувствительных данных, если они помещены в полезную нагрузку в открытом виде[11]. Для обеспечения конфиденциальности данных используется стандарт JSON Web Encryption (JWE).

Подпись (Signature)

Создаётся путём хэширования строки «Base64url(Header).Base64url(Payload)» с использованием секретного ключа (HMAC) либо закрытого ключа (RSA/ECDSA). Подпись обеспечивает:

  • подтверждение издателя;
  • защиту от изменения содержимого токена[12].

Одной из известных уязвимостей, связанных с подписью, является атака «Algorithm Confusion» (путаница алгоритмов). Она возникает, когда сервер некорректно валидирует алгоритм, указанный в заголовке, и позволяет переключаться между асимметричными (например, RS256) и симметричными (HS256) алгоритмами. Злоумышленник может взять публичный ключ, предназначенный для асимметричного шифрования, и использовать его как секрет для создания подписи с симметричным алгоритмом (HS256). Если сервер ожидает токен с любым из этих алгоритмов, он может ошибочно проверить подпись HS256, используя публичный ключ как секрет, и счесть поддельный токен действительным.

В итоговом виде токен выглядит как: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJleGFtcGxlIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c.

1. Аутентификация и генерация токена

  1. Клиент отправляет учётные данные серверу.
  2. При успешной проверке сервер формирует Header и Payload, подписывает их секретом/ключом и возвращает JWT клиенту[13].

2. Хранение на клиенте

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

Хранение токена в веб-хранилищах, таких как `localStorage` или `sessionStorage`, считается небезопасным. Основная причина — уязвимость к атакам типа межсайтового скриптинга (XSS). Если злоумышленнику удаётся внедрить на страницу вредоносный JavaScript-код, он может получить полный доступ к хранилищу и украсть токен[14][15].

Более безопасным подходом является использование cookie с флагом `HttpOnly`. Этот флаг запрещает доступ к cookie из JavaScript, что эффективно защищает от кражи токена через XSS[16]. Однако этот метод уязвим для атак типа межсайтовой подделки запроса (CSRF), если не приняты дополнительные меры защиты[17].

Современной рекомендованной практикой является комбинированная схема с использованием двух токенов — токена доступа (access token) и токена обновления (refresh token)[14]:

  • Токен доступа — короткоживущий токен (например, 5–15 минут), который хранится в памяти клиентского приложения (например, в переменной JavaScript). Это наиболее безопасный способ хранения, так как он недоступен для XSS-атак при перезагрузке страницы, но сам токен теряется при обновлении вкладки[18].
  • Токен обновления — долгоживущий токен, который сохраняется в cookie с максимальными мерами защиты: `HttpOnly` (защита от XSS), `Secure` (передача только по HTTPS) и `SameSite=Strict` или `SameSite=Lax` (защита от CSRF)[19][20].

Эта архитектура минимизирует риски: даже в случае кражи короткоживущего токена доступа ущерб будет ограниченным, а наиболее ценный токен обновления надёжно защищён в cookie.

3. Передача с запросами

При обращении к защищённым ресурсам клиент включает JWT в заголовок Authorization: Bearer <token>[21].

4. Валидация на сервере

Сервер:

  • проверяет подпись токена;
  • удостоверяется, что exp не истёк и другие клеймы (iss, aud) валидны;
  • извлекает данные пользователя и принимает решение об авторизации[22].

5. Обновление (refresh)

Поскольку JWT по своей природе являются stateless (не хранят состояние), одной из ключевых проблем является невозможность досрочного отзыва скомпрометированного токена — он остаётся действительным до истечения своего срока действия[23]. Для решения этой проблемы и повышения общего уровня безопасности применяется механизм обновления с использованием двух токенов: короткоживущего токена доступа (access token) и долгоживущего токена обновления (refresh token).

Схема работы выглядит следующим образом:

  1. Клиентское приложение использует токен доступа для авторизации запросов к защищённым ресурсам API.
  2. Когда срок действия токена доступа истекает, сервер возвращает ошибку авторизации (например, со статусом 401 Unauthorized).
  3. Получив ошибку, клиентское приложение отправляет запрос на специальный эндпоинт (например, /api/refresh), не включая в него никаких данных вручную. Браузер автоматически прикрепляет к этому запросу токен обновления, который хранится в защищённой cookie с флагами HttpOnly, Secure и SameSite.
  4. Сервер получает токен обновления, проверяет его подлинность и валидность (например, сверяясь со списком действующих токенов в базе данных). Это позволяет централизованно отзывать сессии пользователей, просто удаляя их токен обновления[24].
  5. В случае успеха сервер генерирует новую пару токенов: новый токен доступа и, как правило, новый токен обновления (для реализации ротации токенов). Новый токен доступа возвращается в теле ответа, а новый токен обновления устанавливается в cookie, заменяя старый.
  6. Клиентское приложение сохраняет новый токен доступа (например, в памяти) и повторяет исходный запрос, который завершился ошибкой.

Этапы работы с JWT

  1. Создание — сервер формирует Header и Payload, подписывает их выбранным алгоритмом и возвращает клиенту готовый токен[2].
  2. Подпись — обеспечивает целостность и подтверждает источник токена[25].
  3. Передача — клиент отправляет значение в заголовке Authorization: Bearer <token>; коммуникация должна происходить по HTTPS[26].
  4. Проверка — сервер валидирует подпись и контролирует утверждения (exp, iat, jti)[27].
  5. Обновление — по истечении срока действия access-токена клиент обменивает refresh-токен на новую пару токенов, сохраняя непрерывность сессии[28].

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

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

  • Stateless-аутентификация — не требует хранения сессий на сервере, облегчая горизонтальное масштабирование[2].
  • Компактность передачи — удобен для мобильных и IoT-устройств[29].
  • Криптографическая целостность — подпись выявляет любые изменения содержимого[30].
  • Кроссплатформенность — реализуется практически на всех популярных языках[9].
  • Снижение риска CSRF — отсутствие cookie-сессий упрощает защиту[31].

Недостатки

  • Сложность отзыва — действительность токена прекращается лишь после истечения срока либо при использовании «чёрных списков»[30].
  • Повышенный размер — хранит все данные внутри себя, что увеличивает объём трафика.
  • Риск при утечке — украденный токен позволяет злоумышленнику действовать от имени жертвы до истечения exp[32].
  • Жёсткое время жизни — внезапное истечение может ухудшать UX.
  • Уязвимости при слабой конфигурации — выбор устаревших алгоритмов или коротких секретов приводит к компрометации[32].

Сферы применения

  • Аутентификация REST-API — проверка подлинности запросов без повторной передачи учётных данных.
  • Авторизация — хранение ролей и прав доступа в Payload позволяет сервисам принимать решения локально[9].
  • SSO — единый вход для набора приложений по протоколу OpenID Connect.
  • Микросервисные архитектуры — обмен удостоверениями между сервисами без центрального хранилища сессий[30].
  • Мобильные приложения — компактное хранение токена в безопасном хранилище устройства[33].
  • IoT-устройства — подтверждение подлинности сенсоров и шлюзов при обмене телеметрией.
  • Защищённый обмен данными между системами — криптографическая подпись гарантирует целостность и источник сообщения[9].

Инструменты для работы с JWT

Для работы с JSON Web Tokens (JWT) существует множество инструментов: от онлайн-декодеров до специализированных библиотек для разработки и тестирования безопасности.

Библиотеки

Для интеграции JWT в код используются готовые реализации стандарта RFC 7519 для разных языков программирования:

JavaScript/Node.js
* jsonwebtoken
* panva/jose
* nJwt[34]
Python
* PyJWT
* Authlib
Java
* java-jwt (Auth0)
* Nimbus JOSE + JWT
PHP
* firebase/php-jwt
* tymon/jwt-auth
.NET
* System.IdentityModel.Tokens.Jwt
* jwt-dotnet/jwt
Go
* golang-jwt/jwt
Ruby
* jwt[35]

Онлайн-сервисы

Эти инструменты позволяют быстро декодировать токен, проверить его структуру и подпись.

  • jwt.io — декодирование, подпись и проверка токенов в браузере[1].
  • FusionAuth JWT Decoder — интерактивная валидация и просмотр Payload[36].
  • JWT.one — генератор и декодер с поддержкой различных алгоритмов.

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

Примечания

Категории

© Правообладателем данного материала является АНО «Интернет-энциклопедия «РУВИКИ».
Использование данного материала на других сайтах возможно только с согласия АНО «Интернет-энциклопедия «РУВИКИ».