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 состоит из трех основных частей, разделенных точками (.):
- Заголовок (Header):
- Содержит метаданные о токене, включая:
- typ: Тип токена, обычно «JWT».
- alg: Алгоритм подписи, например, HS256 (HMAC SHA-256), RS256 (RSA SHA-256) или none (без подписи).
- Содержит метаданные о токене, включая:
- Полезная нагрузка (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.
- Зарегистрированные (Registered claims): Стандартные, необязательные ключи, такие как:
- Содержит утверждения (claims) — данные о пользователе, токене или другие параметры. Утверждения делятся на:
- Подпись (Signature):
- Создается путем объединения закодированных заголовка и полезной нагрузки, подписанных с использованием секрета или закрытого ключа по алгоритму, указанному в заголовке.
Как работает
JWT используется в клиент-серверных приложениях следующим образом:
- Аутентификация: Клиент (например, веб-приложение) аутентифицируется на сервере авторизации, предоставляя учетные данные, такие как логин и пароль.
- Выдача токенов: Сервер авторизации генерирует JWT (обычно access-токен и refresh-токен), подписывает его и отправляет клиенту.
- Использование access-токена: Клиент включает access-токен в заголовок HTTP-запроса (Authorization: Bearer <token>) для доступа к защищенным ресурсам.
- Проверка токена: Сервер ресурсов (например, API) проверяет подпись токена, его срок действия и утверждения, чтобы разрешить или отклонить запрос.
- Обновление токена: При истечении срока действия access-токена клиент использует refresh-токен для получения нового access-токена от сервера авторизации.
- Повторная аутентификация: Если 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 обеспечивает безопасное и удобное управление доступом, что делает его незаменимым в цифровой экосистеме.