Перейти к содержимому
ecdsa.com
jose (JavaScript)Библиотеки JWT

Сообщение об ошибке

missing required "aud" claim

Также выводится как

  • missing required "iss" claim
  • missing required "exp" claim
  • missing required "sub" claim
  • missing required "iat" claim

Имя утверждения в сообщении зависит от того, какого утверждения нет (`"aud"`, `"iss"`, `"exp"`, `"sub"`, `"iat"`…). В `err.claim` содержится это имя, а `err.reason` равен `"missing"`.

jose (JavaScript) — JWTClaimValidationFailed, code ERR_JWT_CLAIM_VALIDATION_FAILED, reason "missing"

Что это означает

В токене нет утверждения, которое ваши параметры проверки делают обязательным. jose считает утверждение обязательным не только когда вы перечисляете его в `requiredClaims`, но и всякий раз, когда вы просите его проверить: `audience` требует `aud`, `issuer` — `iss`, `subject` — `sub`, а `maxTokenAge` — `iat`. Имя утверждения в кавычках показывает, какого именно не хватает; подпись к этому моменту уже признана верной.

Почему это происходит

Как исправить

  1. 1.

    Записывайте в лог недостающее утверждение и те, что есть в токене

    У объекта ошибки есть свойства `claim`, `reason` и декодированный `payload`. Если записать их в лог, уже по одному запросу видно, что произошло: «издатель не записывает утверждение» или «отправлен не тот токен».

    js
    import { errors, jwtVerify } from "jose";
    
    try {
      await jwtVerify(token, jwks, { algorithms: ["ES256"], audience: "https://api.example.com" });
    } catch (err) {
      if (err instanceof errors.JWTClaimValidationFailed && err.reason === "missing") {
        console.error("token lacks claim:", err.claim, "claims present:", Object.keys(err.payload));
      }
      throw err;
    }
  2. 2.

    Пусть издатель добавляет это утверждение

    Лучше исправить токен, чем смягчать проверку. Именно `aud`, `iss` и `exp` делают JWT безопасным для приёма; RFC 8725 рекомендует включать их в каждый токен.

    js
    import { SignJWT } from "jose";
    
    const token = await new SignJWT({ scope: "orders:read" })
      .setProtectedHeader({ alg: "ES256", kid })
      .setIssuer("https://issuer.example.com")
      .setAudience("https://api.example.com")   // the claim the verifier requires
      .setIssuedAt()
      .setExpirationTime("10m")
      .sign(privateKey);

Связанные ошибки

Открыть всю базу ошибок подписей