Message d’erreur
missing required "aud" claim
Également affiché sous la forme
- missing required "iss" claim
- missing required "exp" claim
- missing required "sub" claim
- missing required "iat" claim
Le nom du claim change selon le claim manquant (`"aud"`, `"iss"`, `"exp"`, `"sub"`, `"iat"`…). `err.claim` contient le nom et `err.reason` vaut `"missing"`.
jose (JavaScript) — JWTClaimValidationFailed, code ERR_JWT_CLAIM_VALIDATION_FAILED, reason "missing"
Ce que cela signifie
Le jeton ne contient pas un claim que vos options de vérification rendent obligatoire. jose considère un claim comme requis non seulement lorsque vous le listez dans `requiredClaims`, mais aussi dès que vous lui demandez de vérifier ce claim : `audience` requiert `aud`, `issuer` requiert `iss`, `subject` requiert `sub` et `maxTokenAge` requiert `iat`. Le nom du claim entre guillemets vous indique lequel est absent ; la signature était déjà valide.
Pourquoi cela se produit
Une option de vérification implique le claim
fréquenteDéfinir `audience: "https://api.example.com"` signifie « le jeton doit être destiné à cette API » – un jeton sans `aud` ne peut pas satisfaire cette condition, donc jose signale le claim comme manquant au lieu de laisser passer le jeton sans rien dire. Il en va de même pour `issuer`, `subject` et `maxTokenAge`.
L’émetteur n’écrit jamais ce claim
fréquenteLes services de jetons internes ou développés maison omettent souvent `aud` ou `exp`. Les jetons sans `exp` n’expirent jamais ; les jetons sans `aud` peuvent être rejoués auprès de n’importe quel service qui fait confiance au même émetteur – deux défauts qui méritent d’être corrigés à la source.
Le claim figure dans requiredClaims
occasionnelle`requiredClaims: ["exp", "jti"]` rend ces claims obligatoires, quelles que soient leurs valeurs. Un type de jeton auquel il manque légitimement l’un d’eux (par exemple un jeton de service à longue durée de vie sans `exp`) échoue ici, et c’est voulu.
Un autre type de jeton a atteint le vérificateur
occasionnelleLes jetons d’actualisation, les jetons de déconnexion ou les jetons propres à un fournisseur sont aussi des JWT, mais portent d’autres ensembles de claims. Si l’ensemble de claims vous semble inhabituel, c’est que le mauvais jeton a été envoyé.
Comment corriger l’erreur
- 1.
Journaliser le claim manquant et les claims présents
L’objet d’erreur expose `claim`, `reason` et le `payload` décodé. Les journaliser permet de distinguer, dès une seule requête, « l’émetteur ne l’écrit pas » de « le mauvais jeton a été envoyé ».
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.
Faire inclure le claim par l’émetteur
Corrigez de préférence le jeton plutôt que d’assouplir le vérificateur. Ce sont `aud`, `iss` et `exp` qui permettent d’accepter un JWT en toute sécurité ; la RFC 8725 recommande que chaque jeton les contienne.
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);