PyJWT (Python)JWT 库
错误信息
It is required that you pass in a value for the "algorithms" argument when calling decode().
PyJWT (Python) — jwt.exceptions.DecodeError
含义
从 PyJWT 2.0 开始,没有显式的 algorithms 列表,jwt.decode() 就拒绝运行。这并不是吹毛求疵:根据令牌自身的头部推断算法,会让算法混淆攻击成为可能(例如,把 RSA 公钥当作 HMAC 密钥来验证 HS256 令牌)。验证方——在服务端配置,攻击者无法触及——必须声明自己接受哪些算法,而 PyJWT 在 API 层面强制执行这一约定,让不安全的调用方式根本写不出来。
原因
为 PyJWT 1.x 编写的代码
常见PyJWT 1.x 允许调用 jwt.decode(token, key),并自行猜测算法。2.0 版本(2020年)把 algorithms 设为必填参数;任何跨越这一版本界限的依赖升级,都会让原本正常工作的代码报出这个错误。
教程或 LLM 生成的代码片段漏掉了它
常见网上许多较早的示例仍在使用两个参数的 decode() 调用。这样的代码片段在固定使用 PyJWT 1.x 的环境中运行正常,但在任何新版本的安装中都会失败。
共享的身份验证辅助函数隐藏了 decode 调用
偶见如果 jwt.decode() 被包装在一个小型内部工具函数中,PyJWT 一升级,所有导入该辅助函数的服务都会同时出错,而回溯信息指向的是包装函数,而不是调用方代码。框架集成(Flask-JWT-Extended、DRF SimpleJWT)会在内部传入 algorithms——通常是自行编写的包装函数遗漏了它。
修复方法
- 1.
显式指定算法
只传入颁发者实际使用的算法——对于 ECDSA 签名的令牌,通常是 ES256。如果一个服务要处理多种令牌,就为每个颁发者分别设置允许列表,而不是把它们合并成一个宽松的列表。
python import jwt payload = jwt.decode( token, public_key_pem, algorithms=["ES256"], # required — and a security control, not boilerplate audience="api://orders", ) - 2.
只查看而不验证时,要显式声明
如果只需要读取声明(调试、记录日志),就明确地关闭验证——并且切勿把结果用于授权决策。
python claims = jwt.decode(token, options={"verify_signature": False}) # or just the header: header = jwt.get_unverified_header(token)