Параметры jwtDecrypt: issuer, audience, clockTolerance

Параметры issuer, audience и clockTolerance в jwtDecrypt отвечают за проверку корректности и допустимости содержимого токена после его расшифрования. Эти настройки относятся к валидации зарегистрированных JWT-claims и используются для защиты от подмены источника токена, неправильного назначения аудитории и проблем, связанных с рассинхронизацией времени между системами.

Параметр issuer задаёт ожидаемого издателя токена и сопоставляется с полем iss внутри JWT после его расшифрования.

Если значение iss в токене не совпадает с ожидаемым, проверка считается проваленной, и выполнение прерывается с ошибкой валидации.

Обычно issuer задаётся как строка, но допускается и массив значений, если система доверяет нескольким источникам.

await jwtDecrypt(jwt, key, {
  issuer: "https://auth.example.com"
});

Вариант с несколькими допустимыми издателями:

await jwtDecrypt(jwt, key, {
  issuer: [
    "https://auth.example.com",
    "https://login.example.org"
  ]
});

Логика проверки сводится к строгому сравнению:

  • если iss отсутствует — токен считается невалидным (если проверка включена)
  • если iss не входит в список допустимых значений — выбрасывается ошибка
  • если совпадение найдено — дальнейшая валидация продолжается

Использование issuer критично в сценариях с OAuth2, OpenID Connect и любыми распределёнными системами, где несколько сервисов могут выпускать токены.

Проверка audience (aud)

Параметр audience определяет допустимого получателя токена и сравнивается с полем aud внутри JWT.

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

Значение aud в JWT может быть строкой или массивом строк, и jose учитывает оба варианта при проверке.

Пример с одной аудиторией:

await jwtDecrypt(jwt, key, {
  audience: "api.service.local"
});

Пример с несколькими допустимыми аудиториями:

await jwtDecrypt(jwt, key, {
  audience: [
    "api.service.local",
    "admin.service.local"
  ]
});

Особенности проверки:

  • если aud в токене массив — достаточно совпадения хотя бы одного значения
  • если aud строка — выполняется прямое сравнение
  • при отсутствии совпадения токен отклоняется

Параметр audience особенно важен в микросервисной архитектуре, где один и тот же Identity Provider может выдавать токены для разных API.

clockTolerance и работа с временными отклонениями

clockTolerance определяет допустимое отклонение системного времени при проверке временных claims:

  • exp — срок действия токена
  • nbf — время, с которого токен становится валидным
  • iat — время выдачи токена

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

Параметр задаётся в секундах:

await jwtDecrypt(jwt, key, {
  clockTolerance: 5
});

В этом примере допускается расхождение времени до 5 секунд в любую сторону.

Как работает clockTolerance при проверке exp

Если токен истёк, но разница меньше допустимой погрешности, он считается валидным:

  • exp = 1000
  • текущее время = 1003
  • clockTolerance = 5

Токен принимается, потому что превышение срока составляет всего 3 секунды.

Если же:

  • текущее время = 1007

то токен будет отклонён (превышение 7 секунд > tolerance 5).

Взаимодействие issuer, audience и clockTolerance

Эти параметры не работают изолированно — они участвуют в общей цепочке проверки JWT после его расшифрования.

Порядок логики обычно следующий:

  1. Расшифрование JWE (если используется jwtDecrypt)
  2. Декодирование payload
  3. Проверка iss (issuer)
  4. Проверка aud (audience)
  5. Проверка временных claims с учётом clockTolerance

Важно, что при любой ошибке на любом этапе дальнейшая обработка прекращается.

Комбинированное использование параметров

В реальных приложениях эти параметры почти всегда используются вместе:

const payload = await jwtDecrypt(jwt, key, {
  issuer: "https://auth.example.com",
  audience: "api.service.local",
  clockTolerance: 10
});

Такая конфигурация означает:

  • токен должен быть выпущен строго указанным провайдером
  • токен должен быть предназначен конкретному сервису
  • допускается временная погрешность до 10 секунд

Типичные ошибки при настройке

Неправильная конфигурация этих параметров часто приводит к неочевидным сбоям:

Несовпадение issuer

Частая ошибка — использование разных URL в разных окружениях:

  • прод: https://auth.company.com
  • staging: https://auth.staging.company.com

Если issuer не адаптирован под окружение, все токены будут отклоняться.

Неверный audience

Ошибка возникает, когда:

  • фронтенд запрашивает токен для одного API
  • а backend проверяет другой audience

В результате токен формально валиден, но не подходит по назначению.

Отсутствие clockTolerance

Без этого параметра даже минимальные расхождения времени приводят к нестабильным ошибкам:

  • кратковременные отклонения времени
  • задержки синхронизации NTP
  • различия между контейнерами в кластере

Поведение при отключении проверок

Если issuer или audience не указаны, соответствующие проверки не выполняются. Это снижает безопасность, так как токен перестаёт быть привязанным к конкретному источнику и потребителю.

clockTolerance при отсутствии значения считается равным 0, что означает строгую проверку времени без допуска погрешностей.

Практическая интерпретация безопасности

Эти три параметра формируют базовый слой доверия к JWT:

  • issuer отвечает за источник
  • audience отвечает за назначение
  • clockTolerance отвечает за устойчивость к временным расхождениям

Именно их комбинация позволяет предотвратить повторное использование токенов, подмену контекста и ошибки в распределённых системах аутентификации.