エラーメッセージ
Audience doesn't match
別の表記
- jwt.exceptions.InvalidAudienceError: Audience doesn't match
PyJWT (Python) — jwt.exceptions.InvalidAudienceError
このエラーの意味
トークンには `aud` クレームがあり、`jwt.decode()` には `audience=` を渡していますが、一致する値が 1 つもありません。PyJWT は、トークンのオーディエンスの少なくとも 1 つが、許可したオーディエンスのいずれかと等しい場合にトークンを受け入れますが、今回はどれも一致しませんでした。署名は有効でしたが、トークンは別の受信者向けに発行されたものです。
発生する理由
トークンが別の API 向けに発行された
よくある1 つの ID プロバイダーが複数のサービスの前段にある場合、クライアントはサービス A 向けに発行されたトークンを、うっかりサービス B に送ってしまいがちです。それを拒否することこそが、オーディエンスのチェックの目的です。
同じ識別子の表記が異なる
よくある文字列の完全一致で比較されます。末尾のスラッシュ、`http` と `https` の違い、クライアント ID と API 識別子の URL の違い、大文字の混在は、いずれも別のオーディエンスとみなされます。
ID トークンが API に届いている
ときどきOpenID Connect の ID トークンは、`aud` にクライアントアプリケーションの ID を持っています。API が受け取るべきなのは、その API 向けに発行されたアクセストークンです。ID トークンを転送すると、ここで失敗します。
修正方法
- 1.
トークンの aud と、設定したオーディエンスを比較する
検証なしのデコードは中身の確認にだけ使い、そのうえで正確な識別子を指定して検証してください。トークンが誤ったオーディエンス向けに発行されていた場合はクライアントのトークンリクエストを、識別子のつづりが間違っていた場合は検証者を修正してください。
python unverified = jwt.decode(token, options={"verify_signature": False}) print(repr(unverified.get("aud"))) # str or list[str] claims = jwt.decode( token, signing_key, algorithms=["ES256"], audience="https://api.example.com/orders", # must equal one of the token's aud values issuer="https://issuer.example.com/", ) - 2.
複数の識別子を明示的に許可する
`audience` にはリストを指定できます。1 つの API が正当に複数の識別子を持つ場合はリストを使ってください。エラーを消すために `options={"verify_aud": False}` を渡してはいけません。
python # Any one of these may appear in the token's aud. claims = jwt.decode(token, signing_key, algorithms=["ES256"], audience=["orders-api", "https://api.example.com/orders"])