You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JWT解码报错JWTClaimsError:Subject必须为字符串,如何修复?

修复jose.exceptions.JWTClaimsError: Subject must be a string错误

核心原因

jose库对JWT的sub(subject)字段类型校验非常严格,必须是Python原生str类型——哪怕是数字转成的字符串,如果是numpy.str_、pandas.StringDtype这类非原生str,或者编码时sub意外变回非字符串类型,都会触发这个错误。

具体修复步骤

  • 编码阶段强制转原生str:在编码JWT前,明确把sub字段转为Python原生字符串,不要依赖自动转换。比如在你的create_access_token函数里加这一步:

    async def create_access_token(data: dict):
        to_encode = data.copy()
        # 强制将sub转为原生str,覆盖原类型
        if "sub" in to_encode:
            to_encode["sub"] = str(to_encode["sub"])
        # 执行编码
        encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
        # 可选:打印调试,确认sub类型
        print("编码前sub类型:", type(to_encode["sub"]))
        return encoded_jwt
    
  • 排查解码阶段的校验配置:解码时不要给jwt.decode加多余的校验选项,确保只指定正确的算法:

    # 正确的解码示例
    decoded_token = jwt.decode(
        token,
        SECRET_KEY,
        algorithms=[ALGORITHM],
        # 不要加不必要的options,比如不要强制校验sub的额外规则
    )
    
  • 检查sub的来源类型:如果sub是从数据库取的数字ID(比如int类型)、ORM模型字段(比如SQLAlchemy的Integer类型),要确保在传入create_access_token前没有被意外转回非字符串类型。可以在传入前打印类型确认:

    user_id = user.id  # 假设是数据库返回的int类型
    print("传入create_access_token前的sub类型:", type(user_id))
    token = await create_access_token({"sub": str(user_id)})
    
  • 避免空字符串的sub:如果sub是空字符串,部分jose版本也会触发该错误,确保sub是有实际内容的字符串。

调试技巧

在编码后、解码前打印encoded_jwt,复制到jwt.io上解析,查看sub字段的类型——如果jwt.io显示sub是数字而非字符串,说明编码时没转对类型,回到编码阶段排查。

内容的提问来源于stack exchange,提问作者Say

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 08:52:42