JSON Web Token
JSON Web Token (JWT) — это открытый стандарт (RFC 7519) для создания компактных и самодостаточных токенов доступа, предназначенных для передачи информации между двумя сторонами в виде JSON-объекта. JWT используется в системах аутентификации и авторизации, а также для безопасного обмена данными. Токен может быть проверен и доверен, поскольку он цифрово подписан (обычно с помощью HMAC или RSA/ECDSA). JWT компактен, что позволяет передавать его в URL, в HTTP-заголовках или в теле POST-запроса.
История
Стандарт JWT был разработан в 2010 году инженерами компании Atos, в частности, Джоном Брэдли и Натаниэлем Саком. В 2011 году он был принят как RFC 7519 под эгидой IETF (Internet Engineering Task Force). Изначально JWT создавался как расширение стандарта JSON Web Signature (JWS) и JSON Web Encryption (JWE), которые описывают подписание и шифрование данных в формате JSON. Основной целью JWT было создание простого и безопасного механизма для передачи утверждений (claims) между сторонами, который не требует хранения состояния на сервере (stateless). В 2015 году JWT стал частью спецификации OAuth 2.0 (RFC 7519) и получил широкое распространение в веб-разработке, особенно в микросервисной архитектуре и одностраничных приложениях (SPA). В России JWT активно используется в государственных информационных системах (например, в ЕСИА — Единой системе идентификации и аутентификации) и в коммерческих сервисах.
Структура токена
JWT состоит из трёх частей, разделённых точками (.), и имеет следующий формат: xxxxx.yyyyy.zzzzz. Каждая часть представляет собой Base64url-кодированный JSON-объект.
Заголовок (Header)
Заголовок содержит метаданные о токене: тип токена (обычно "typ": "JWT") и алгоритм подписи (например, "alg": "HS256" для HMAC-SHA256 или "alg": "RS256" для RSA). Пример заголовка:
``json { "alg": "HS256", "typ": "JWT" } ``
Полезная нагрузка (Payload)
Полезная нагрузка содержит утверждения (claims) — данные, которые передаются в токене. Утверждения делятся на три типа:
- Зарегистрированные (registered): стандартные ключи, определённые в RFC 7519, такие как
iss(issuer — издатель),sub(subject — субъект),aud(audience — аудитория),exp(expiration — время истечения),nbf(not before — не ранее),iat(issued at — время выдачи),jti(JWT ID — уникальный идентификатор токена). - Публичные (public): произвольные имена, которые могут быть зарегистрированы в реестре IANA, но обычно используются в рамках конкретной системы.
- Частные (private): пользовательские утверждения, согласованные между сторонами (например,
user_id,role).
Пример полезной нагрузки:
``json { "sub": "1234567890", "name": "Иван Иванов", "iat": 1516239022, "exp": 1516242622 } ``
Подпись (Signature)
Подпись создаётся путём кодирования заголовка и полезной нагрузки в Base64url, объединения их через точку и применения алгоритма подписи к полученной строке с использованием секретного ключа (для HMAC) или закрытого ключа (для RSA/ECDSA). Подпись позволяет проверить, что токен не был изменён после создания, и подтвердить его подлинность. Пример создания подписи для HMAC-SHA256:
`` HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret ) ``
Принцип работы
JWT используется в схемах аутентификации и авторизации, чаще всего в паре с протоколом OAuth 2.0. Процесс работы выглядит следующим образом:
- Аутентификация: Пользователь вводит логин и пароль на клиенте (например, веб-приложении). Клиент отправляет эти данные на сервер аутентификации.
- Выдача токена: Сервер проверяет учётные данные, и в случае успеха создаёт JWT, подписывает его и возвращает клиенту.
- Хранение токена: Клиент сохраняет JWT (обычно в
localStorage,sessionStorageили в HTTP-куках с флагомHttpOnly). - Отправка запросов: При каждом запросе к защищённому ресурсу клиент добавляет JWT в HTTP-заголовок
Authorizationв форматеBearer <token>. - Верификация: Сервер ресурсов проверяет подпись JWT, срок действия и другие утверждения. Если токен валиден, сервер извлекает данные из полезной нагрузки и предоставляет доступ.
Основное преимущество JWT — отсутствие необходимости хранить сессию на сервере (stateless). Сервер может проверить токен автономно, без обращения к базе данных или кэшу.
Классификация алгоритмов подписи
JWT поддерживает два основных типа алгоритмов:
- Симметричные (HMAC): Используется один секретный ключ как для создания, так и для проверки подписи. Примеры: HS256, HS384, HS512. Требуют, чтобы ключ был известен только серверу.
- Асимметричные (RSA, ECDSA): Используется пара ключей — закрытый ключ для подписи и открытый ключ для проверки. Примеры: RS256, RS384, RS512, ES256, ES384, ES512. Позволяют разделять роли: сервер аутентификации подписывает токен закрытым ключом, а любой сервер ресурсов может проверить его открытым ключом.
Применение
JWT широко применяется в современных веб-приложениях и API:
- Аутентификация пользователей: JWT используется в системах единого входа (SSO), например, в протоколах OpenID Connect (OIDC) и OAuth 2.0.
- Авторизация в микросервисах: Каждый микросервис может проверить JWT без обращения к центральному серверу аутентификации, что упрощает архитектуру.
- Обмен данными между системами: JWT используется для передачи утверждений между доверенными сторонами, например, между веб-приложением и API.
- Мобильные приложения: JWT компактен и легко передаётся в HTTP-заголовках, что удобно для мобильных клиентов.
- Государственные информационные системы: В России JWT применяется в ЕСИА (Единая система идентификации и аутентификации) для авторизации доступа к государственным услугам через портал «Госуслуги».
Критика и ограничения
Несмотря на популярность, JWT имеет ряд недостатков:
- Неотзываемость: Поскольку JWT stateless, отозвать токен до истечения его срока сложно. Для решения этой проблемы используются чёрные списки (blacklist) или короткие сроки жизни токенов.
- Размер: JWT может быть большим, если содержит много утверждений, что увеличивает размер HTTP-заголовков.
- Безопасность хранения: Если JWT хранится в
localStorage, он уязвим для XSS-атак. Рекомендуется использоватьHttpOnly-куки. - Уязвимость к атакам с подменой алгоритма: Если сервер не проверяет алгоритм подписи, злоумышленник может изменить заголовок на
noneили на симметричный алгоритм, используя открытый ключ как секретный. Для защиты необходимо явно указывать допустимые алгоритмы и проверять подпись. - Сложность управления ключами: При использовании асимметричных алгоритмов требуется безопасное хранение и ротация ключей.
Интересные факты
- JWT является основой для стандарта OpenID Connect (OIDC), который расширяет OAuth 2.0 для аутентификации.
- В 2015 году JWT был включён в стандарт RFC 7519, который также описывает JSON Web Signature (JWS) и JSON Web Encryption (JWE).
- JWT может быть зашифрован (JWE) для обеспечения конфиденциальности данных, а не только подписан.
- В России JWT используется в системе «Московская электронная школа» для авторизации доступа к образовательным ресурсам.
Источники
- RFC 7519 — JSON Web Token (JWT) (IETF, 2015).
- RFC 7515 — JSON Web Signature (JWS) (IETF, 2015).
- RFC 7516 — JSON Web Encryption (JWE) (IETF, 2015).
- OpenID Connect Core 1.0 (OpenID Foundation, 2014).
- Документация ЕСИА (Единая система идентификации и аутентификации), Министерство цифрового развития, связи и массовых коммуникаций РФ.
- OAuth 2.0 Authorization Framework (RFC 6749, IETF, 2012).
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →