Fehlermeldung
unexpected "aud" claim value
jose (JavaScript) — JWTClaimValidationFailed, code ERR_JWT_CLAIM_VALIDATION_FAILED
Was der Fehler bedeutet
Die Signatur wurde erfolgreich geprüft, aber der Claim `aud` des Tokens enthält nicht den Wert, den du `jwtVerify` als `audience` übergeben hast. jose vergleicht Strings exakt: Die Prüfung ist bestanden, wenn mindestens ein Wert in `aud` des Tokens (ein String oder ein Array) einer der von dir erlaubten Audiences entspricht. Das Token ist echt – es wurde nur für einen anderen Empfänger ausgestellt. Würdest du es akzeptieren, ließe sich ein für eine API ausgestelltes Token bei einer anderen erneut vorlegen.
Warum der Fehler auftritt
Das Token wurde für eine andere API ausgestellt
häufigEin Autorisierungsserver bedient oft mehrere Ressourcenserver. Ein Client, der ein Token für die Bestell-API erhalten hat und es an die Abrechnungs-API sendet, bekommt genau diesen Fehler – die Prüfung tut ihre Arbeit. Die Eigenschaft `err.payload` des Fehlers zeigt die Claims, die das Token tatsächlich trägt.
Dieselbe API, anders geschriebener Bezeichner
häufigDer Abgleich der Audience ist bytegenau: `https://api.example.com` und `https://api.example.com/` (Schrägstrich am Ende), http und https oder ein logischer Name wie `api://orders` und die URL der API sind jeweils unterschiedliche Werte. Identity Provider übernehmen den Bezeichner wörtlich aus ihrer Konfiguration, deshalb muss der Prüfer dieselbe Schreibweise verwenden.
Ein ID-Token, wo ein Access Token erwartet wird
gelegentlichIn OpenID Connect ist `aud` des ID-Tokens die Client-ID der Anwendung, die den Nutzer angemeldet hat, nicht deine API. Frontends, die das ID-Token statt des Access Tokens weiterreichen, scheitern deshalb an der Audience-Prüfung jeder API dahinter.
Der Client hat keine bestimmte Audience angefordert
gelegentlichMehrere Provider (Auth0, benutzerdefinierte Autorisierungsserver von Okta, Keycloak mit Audience-Mappern) tragen deine API nur dann in `aud` ein, wenn die Token-Anfrage sie nennt. Ohne den Parameter `audience` oder den Parameter `resource` aus RFC 8707 wird das Token für eine Standard-Audience ausgestellt, etwa den Userinfo-Endpunkt.
So behebst du den Fehler
- 1.
Inhalt des Tokens neben dem erwarteten Wert ausgeben
Dekodiere die Claims, ohne ihnen zu vertrauen, und vergleiche `aud` Zeichen für Zeichen mit deiner Option `audience`. Korrigiere die Seite, die falsch ist – die Option des Prüfers oder die Konfiguration des Ausstellers –, aber behalte die Prüfung bei.
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.
Token für die API anfordern, die du aufrufst
Wurde das Token für eine andere Audience ausgestellt, gehört die Korrektur in den Client: Nenne die Ziel-API in der Token-Anfrage, damit der Autorisierungsserver sie in `aud` einträgt.
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.
Mehrere Bezeichner explizit zulassen, wenn sie alle dir gehören
`audience` akzeptiert ein Array. Liste jeden Bezeichner auf, der diese API legitim benennt (etwa bei einer Migration von einer URL auf einen logischen Namen), statt die Option zu entfernen – ohne `audience` prüft jose `aud` überhaupt nicht.
js await jwtVerify(token, jwks, { algorithms: ["ES256"], audience: ["https://api.example.com/orders", "orders-api"], // any one must match });