You need to enable JavaScript to run this app. FastAPI+SQLAlchemy实现JWT校验时payload['sub']查询用户返回None问题
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI+SQLAlchemy实现JWT校验时payload['sub']查询用户返回None问题

代码问题汇总

核心问题(导致get_user_by_id返回None的直接原因)

  • 注册逻辑重复创建用户,生成token的用户未入库:
    你在create_user接口中先手动实例化了一个User对象,用这个临时对象的id生成激活token、设置confirmation字段,但最后调用users.register_user(form_data)时,该方法内部又重新实例化了一个全新的User对象存入数据库,你之前设置过confirmation的临时用户根本没有入库,所以verify接口通过token里的sub(也就是临时用户的id)查库肯定返回None。
    正确的做法是不要在接口层重复实例化User,所有数据库操作都放到数据访问层的方法里,register_user方法要接收生成好的confirmation值,入库后返回正确的用户对象。

其他严重问题

  • 参数类型不匹配导致查询失效:
    User表的id字段是UUID(as_uuid=True)类型,你调用get_user_by_id时传入的是字符串类型的payload['sub'],部分异步SQLAlchemy驱动不会自动把字符串转成UUID对象,需要手动转:
    from uuid import UUID
    user = await users.get_user_by_id(id=UUID(payload['sub']))
    
  • jti校验逻辑完全错误:
    你写的await users.get_confirmation_uuid(str(User.confirmation)) != payload['jti']存在两个错误:
    1. User.confirmation是模型类的属性,直接转str拿到的是SQL表达式字符串,不是当前查询到的用户的confirmation值
    2. get_confirmation_uuid返回的是SQLAlchemy查询结果对象,不是字符串,和payload['jti']对比永远不成立
      正确的做法是直接用已经查到的user对象对比,且get_confirmation_uuid方法完全多余,可以直接删除:
    if not user or str(user.confirmation) != payload['jti']:
        raise invalid_token_error
    
  • 用户激活修改未持久化:
    verify接口中你修改了user.confirmation = None和user.is_active = True之后,既没有把修改add到session,也没有commit/flush,修改不会同步到数据库。而且你最后调用register_user(user)是完全错误的,这个方法是用来新建用户的,会重复创建数据。
    正确的做法是在Users类里新增一个更新用户的方法,或者直接在verify逻辑里提交修改:
    self.db_session.add(user)
    await self.db_session.commit()
    await self.db_session.refresh(user)
    
  • 密码存储逻辑错误:
    你在create_user接口中已经用Auth.get_password_hash(form_data.password)计算了密码哈希,但是register_user方法里直接把user.password(明文密码)赋值给了hashed_password字段,导致存的是明文密码,完全不符合安全要求。
  • token过期异常捕获错误:
    你在verify接口中捕获的是jwt.JWSError,但JWT过期抛出的是jwt.ExpiredSignatureError,会导致过期token不会返回正确的“Token已过期”提示,而是走500错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 08:06:03