Authlib 是面向 Flask、Django、Starlette 和 httpx 的完整 OAuth 2.0 与 OpenID Connect 工具包,authlib.jose 则是它赖以构建的 JWS、JWE、JWK 和 JWT 层。在 1.9.1 中导入它会输出 authlib.jose module is deprecated, please use joserfc instead.;维护者已把 JOSE 代码移到独立的 joserfc 包中,旧模块为保持兼容会保留到 2.0。现有代码仍能运行,但新代码应该基于 joserfc 编写。
最容易让人出错的细节是:decode() 只检查签名。一个一小时前就已过期的令牌,decode() 照样返回,没有任何报错;只有调用 claims.validate() 时才会检查过期时间、颁发者和受众——而且要在 claims_options 中把 exp 和 iss 标记为必需(essential),否则缺少它们的令牌也会通过。除非向 validate() 传入宽限时间(leeway),否则不留任何宽限。
算法的处理方式取决于所用的对象。模块级的 jwt 接受它所知道的所有算法,并按密钥类型选择算法,因此用 EC 密钥验证 RS256 令牌时,在导入密钥这一步就失败了;而 JsonWebToken(["ES256"]) 实例只允许你列出的算法。只要列出 none,未签名的令牌就能验证通过,因此切勿让配置中的值最终进入这个列表。看起来像 PEM 公钥的 HMAC 密钥会被拒绝,并报错 This key may not be safe to import;ES256 也会拒绝 P-384 密钥。
1.9.1 支持的算法涵盖 HS、RS、PS 和 ES 系列,以及 ES256K 和 EdDSA,但不支持 Ed25519 或 Ed448 这两个名称。ES256 签名是 64 字节的原始 r‖s;DER 签名会报错 bad_signature,可以借助 JWT 调试器和 DER ⇄ 原始格式转换器诊断。要查看某个身份提供商的令牌和密钥是什么样子,可以使用 OIDC 令牌校验器和 JWKS 检测。
示例使用受限的 JsonWebToken 实例,并显式校验声明——这正是模块级 API 省略掉的两个步骤。