setIssuedAt, setNotBefore, setIssuer, setSubject, setAudience, setJti

В библиотеке jose работа с JWT строится вокруг формирования набора стандартных и пользовательских клеймов (claims), которые затем включаются в подписываемый токен. Методы setIssuedAt, setNotBefore, setIssuer, setSubject, setAudience и setJti используются при построении полезной нагрузки токена через SignJWT и позволяют точно управлять семантикой и жизненным циклом JWT.


Метод setIssuedAt() добавляет в токен стандартный клейм iat (issued at) — момент времени, когда токен был выдан.

import { SignJWT } from 'jose';

const jwt = await new SignJWT({ role: 'admin' })
  .setIssuedAt()
  .sign(key);

Особенности поведения

  • По умолчанию используется текущее время в формате UNIX timestamp (секунды).
  • Может принимать числовое значение, если требуется задать кастомное время выдачи:
.setIssuedAt(1710000000)

Роль в проверке токена

iat используется для:

  • определения возраста токена
  • реализации политик ротации токенов
  • аудита выдачи

setNotBefore

Метод setNotBefore() задаёт клейм nbf (not before), который определяет момент, до которого токен считается недействительным.

const jwt = await new SignJWT({ role: 'user' })
  .setNotBefore('10m')
  .sign(key);

Форматы значений

Поддерживаются несколько вариантов:

  • абсолютное время (timestamp)

  • относительное время в формате временных интервалов:

    • "10s"
    • "5m"
    • "2h"

Поведение при проверке

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

Практическое применение

  • отложенная активация токенов
  • синхронизация доступа между сервисами
  • предотвращение преждевременного использования токена

setIssuer

Метод setIssuer() задаёт клейм iss (issuer), идентифицирующий эмитента токена.

const jwt = await new SignJWT({ role: 'user' })
  .setIssuer('auth-service')
  .sign(key);

Семантика issuer

iss используется для:

  • идентификации сервиса, выпустившего токен
  • разделения доверенных источников
  • валидации в распределённых системах

Проверка на стороне получателя

При верификации можно требовать совпадение issuer:

jwtVerify(token, key, {
  issuer: 'auth-service'
});

Несовпадение приводит к ошибке валидации.


setSubject

Метод setSubject() формирует клейм sub (subject), который описывает субъект токена.

const jwt = await new SignJWT({ role: 'user' })
  .setSubject('user:12345')
  .sign(key);

Назначение subject

sub обычно используется для:

  • идентификации пользователя
  • привязки токена к сущности (user, service, device)
  • построения ACL-логики

Рекомендации по структуре

Часто используется формат с неймспейсом:

  • user:123
  • service:billing
  • device:mobile:abc

Это снижает риск коллизий между типами сущностей.


setAudience

Метод setAudience() задаёт клейм aud (audience), который определяет целевую аудиторию токена.

const jwt = await new SignJWT({ role: 'user' })
  .setAudience('api-service')
  .sign(key);

Форматы значений

  • строка
  • массив строк (если несколько получателей)
.setAudience(['api-service', 'analytics-service'])

Роль в архитектуре

aud используется для:

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

Проверка аудитории

jwtVerify(token, key, {
  audience: 'api-service'
});

При несовпадении аудитории токен считается недействительным.


setJti

Метод setJti() задаёт клейм jti (JWT ID) — уникальный идентификатор токена.

const jwt = await new SignJWT({ role: 'user' })
  .setJti('550e8400-e29b-41d4-a716-446655440000')
  .sign(key);

Назначение jti

jti используется для:

  • предотвращения повторного использования токена (replay attacks)
  • чёрных списков токенов
  • отслеживания конкретных экземпляров JWT

Генерация значений

Обычно используется UUID или аналогичный уникальный идентификатор.

Пример генерации:

import { randomUUID } from 'crypto';

.setJti(randomUUID())

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

При хранении активных сессий jti позволяет:

  • отозвать конкретный токен без влияния на остальные
  • реализовать систему logout на стороне сервера
  • контролировать однократное использование токена

Комбинирование клеймов в SignJWT

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

const jwt = await new SignJWT({ role: 'admin' })
  .setIssuer('auth-service')
  .setSubject('user:123')
  .setAudience('api-service')
  .setIssuedAt()
  .setNotBefore('0s')
  .setJti(randomUUID())
  .sign(key);

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

  • происхождение
  • субъект
  • целевую систему
  • временные ограничения
  • уникальность экземпляра
  • момент создания

Особенности обработки в jose

При валидации библиотека jose учитывает эти поля через jwtVerify, где можно явно задать ожидаемые значения:

jwtVerify(token, key, {
  issuer: 'auth-service',
  audience: 'api-service'
});

iat, nbf и exp (если используется) проверяются автоматически при включённых проверках времени.


Практическая модель использования

В типичной архитектуре:

  • iss фиксирует сервис авторизации
  • sub связывает токен с пользователем
  • aud ограничивает сервисы потребления
  • iat фиксирует момент выпуска
  • nbf управляет задержкой активации
  • jti обеспечивает уникальность и контроль сессий

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