Message d’erreur
unexpected "aud" claim value
jose (JavaScript) — JWTClaimValidationFailed, code ERR_JWT_CLAIM_VALIDATION_FAILED
Ce que cela signifie
La signature a été vérifiée, mais le claim `aud` du jeton ne contient pas la valeur que vous avez passée comme `audience` à `jwtVerify`. jose compare des chaînes exactes : le contrôle réussit lorsqu’au moins une valeur de l’`aud` du jeton (une chaîne ou un tableau) est égale à l’une des audiences que vous autorisez. Le jeton est authentique – il a simplement été émis pour un autre destinataire, et l’accepter permettrait de rejouer contre une API un jeton créé pour une autre.
Pourquoi cela se produit
Le jeton a été émis pour une autre API
fréquenteUn même serveur d’autorisation dessert souvent plusieurs serveurs de ressources. Un client qui a obtenu un jeton pour l’API des commandes et l’envoie à l’API de facturation obtient exactement cette erreur – le contrôle fait son travail. La propriété `err.payload` de l’erreur montre les claims que le jeton porte réellement.
Même API, identifiant écrit différemment
fréquenteLa correspondance d’audience est exacte à l’octet près : `https://api.example.com` et `https://api.example.com/` (barre oblique finale), http et https, ou un nom logique tel que `api://orders` et l’URL de l’API sont autant de valeurs différentes. Les fournisseurs d’identité recopient l’identifiant tel quel depuis leur configuration : le vérificateur doit donc utiliser la même écriture.
Un jeton d’ID envoyé là où un jeton d’accès est attendu
occasionnelleDans OpenID Connect, l’`aud` du jeton d’ID est l’ID client de l’application qui a connecté l’utilisateur, et non votre API. Les front-ends qui transmettent le jeton d’ID au lieu du jeton d’accès échouent donc au contrôle d’audience de toutes les API situées derrière eux.
Le client n’a pas demandé d’audience précise
occasionnellePlusieurs fournisseurs (Auth0, les serveurs d’autorisation personnalisés d’Okta, Keycloak avec des mappeurs d’audience) n’inscrivent votre API dans `aud` que si la requête de jeton la nomme. Sans le paramètre `audience` ou le paramètre `resource` de la RFC 8707, le jeton est émis pour une audience par défaut, comme le point de terminaison userinfo.
Comment corriger l’erreur
- 1.
Afficher ce que porte le jeton à côté de ce que vous attendez
Décodez les claims sans leur faire confiance et comparez `aud` avec votre option `audience`, caractère par caractère. Corrigez le côté qui est en tort (l’option du vérificateur ou la configuration de l’émetteur), mais conservez le contrôle.
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.
Demander un jeton pour l’API que vous appelez
Lorsque le jeton a été émis pour une autre audience, la correction se fait côté client : nommez l’API cible dans la requête de jeton pour que le serveur d’autorisation l’inscrive dans `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.
Autoriser explicitement plusieurs identifiants, s’ils sont tous à vous
`audience` accepte un tableau. Listez chaque identifiant qui désigne légitimement cette API (par exemple lors d’une migration d’une URL vers un nom logique) au lieu de supprimer l’option : sans `audience`, jose ne vérifie pas du tout `aud`.
js await jwtVerify(token, jwks, { algorithms: ["ES256"], audience: ["https://api.example.com/orders", "orders-api"], // any one must match });