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

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

unexpected "aud" claim value

jose (JavaScript) — JWTClaimValidationFailed, code ERR_JWT_CLAIM_VALIDATION_FAILED

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

Подпись верна, но утверждение `aud` токена не содержит значения, которое вы передали в `jwtVerify` как `audience`. jose сравнивает строки точно: проверка проходит, если хотя бы одно значение в `aud` токена (строке или массиве) равно одной из разрешённых вами аудиторий. Токен подлинный, просто он выпущен для другого получателя; если его принять, токен, выпущенный для одного API, можно будет повторно предъявить другому.

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

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

  1. 1.

    Выведите рядом то, что есть в токене, и то, что вы ожидаете

    Декодируйте утверждения, не доверяя им, и посимвольно сравните `aud` со своим параметром `audience`. Исправьте ту сторону, где ошибка (параметр проверяющей стороны или конфигурацию издателя), но саму проверку оставьте.

    js
    import { decodeJwt, jwtVerify } from "jose";
    
    console.log("token aud:", decodeJwt(token).aud); // string or array of strings
    
    await jwtVerify(token, jwks, {
      algorithms: ["ES256"],
      issuer: "https://issuer.example.com",
      audience: "https://api.example.com/orders", // exact string match
    });
  2. 2.

    Запрашивайте токен для того API, который вызываете

    Если токен выпущен для другой аудитории, исправлять нужно на стороне клиента: укажите целевой API в запросе токена, чтобы сервер авторизации записал его в `aud`.

    bash
    # OAuth 2.0 client credentials: ask the authorization server for a token
    # minted for the API you are about to call (Auth0 uses "audience",
    # RFC 8707 resource indicators use "resource").
    curl -s https://issuer.example.com/oauth/token \
      -d grant_type=client_credentials \
      -d client_id="$CLIENT_ID" -d client_secret="$CLIENT_SECRET" \
      -d audience=https://api.example.com/orders
  3. 3.

    Явно разрешите несколько идентификаторов, если все они ваши

    `audience` принимает массив. Перечислите все идентификаторы, которые законно обозначают этот API (например, на время миграции с URL на логическое имя), но не удаляйте сам параметр: без `audience` jose вообще не проверяет `aud`.

    js
    await jwtVerify(token, jwks, {
      algorithms: ["ES256"],
      audience: ["https://api.example.com/orders", "orders-api"], // any one must match
    });

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

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