PyJWT (Python)JWT 库
错误信息
Audience doesn't match
也可能输出为
- jwt.exceptions.InvalidAudienceError: Audience doesn't match
PyJWT (Python) — jwt.exceptions.InvalidAudienceError
含义
令牌带有 `aud` 声明,你也向 `jwt.decode()` 传入了 `audience=`,但两者没有任何相同的值。只要令牌的受众中至少有一个等于你允许的某个受众,PyJWT 就会接受该令牌;而这里一个都没有。签名是有效的——只是令牌签发给了另一个接收方。
原因
令牌是为另一个 API 签发的
常见当多个服务共用同一个身份提供商时,客户端很容易把为服务 A 签发的令牌发送给服务 B。拒绝这种令牌正是受众检查的目的。
同一标识符的不同写法
常见这里做的是精确的字符串比较:末尾多一个斜杠、`http` 与 `https`、客户端 ID 与 API 标识符 URL,或者大小写不同,都算作不同的受众。
ID 令牌被发送到了 API
偶见OpenID Connect 的 ID 令牌在 `aud` 中携带的是客户端应用的 ID。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` 可以接受列表。当一个 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"])