PyJWT (Python)JWT 库
错误信息
The specified alg value is not allowed
也可能输出为
- jwt.exceptions.InvalidAlgorithmError: The specified alg value is not allowed
PyJWT (Python) — jwt.exceptions.InvalidAlgorithmError
含义
令牌头部中的 `alg` 不在你传给 `jwt.decode()` 的 `algorithms` 列表中。PyJWT 在验证签名之前就检查这一点,因为头部是由生成令牌的一方选定的,不得由它来决定如何验证。令牌可能签名正确——只是用了你没有允许的算法。
原因
颁发者更换了算法
常见提供商从 RS256 迁移到 ES256(或者新增 EdDSA 密钥)后,固定使用旧值的验证方就会出错。失败恰好从上线那一刻开始,并且只影响新签发的令牌。
JWK 限定了另一种算法
偶见传入 `PyJWK`(例如来自 `PyJWKClient`)时,它的 `alg` 同样会限制验证。标记为 RS256 的 JWK 无法验证 ES256 令牌。
来自别处的令牌
偶见来自其他颁发者的令牌、发往公开 API 的内部 HS256 令牌,或者针对受 RSA 保护的 API、带有 `alg: "none"` 或 `HS256` 的探测请求。在这些情况下,拒绝是正确的。
修复方法
- 1.
先读取头部
`jwt.get_unverified_header()` 可以在不信任任何内容的前提下显示 `alg` 和 `kid`。把结果与你的允许列表以及颁发者发布的密钥进行对比。
python print(jwt.get_unverified_header(token)) # {'alg': 'ES256', 'kid': '...', 'typ': 'JWT'} - 2.
只允许颁发者使用的那种算法
把颁发者使用的算法放进 `algorithms`,并从它的 JWKS 中查找密钥。迁移期间同时列出两种算法,并通过 `kid` 让每种算法与各自的密钥对应。
python from jwt import PyJWKClient jwks = PyJWKClient("https://issuer.example.com/.well-known/jwks.json") signing_key = jwks.get_signing_key_from_jwt(token) claims = jwt.decode( token, signing_key.key, algorithms=["ES256"], # the algorithm(s) your issuer actually uses, never the token's own header audience="https://api.example.com", )