FastAPI JWT认证报错:TokenData的id需为有效字符串
解决JWT令牌认证时的Pydantic ValidationError问题
问题根源
错误提示明确指出:TokenData的id字段期望字符串类型,但实际传入了整数(14)。核心原因有三点:
- 数据库中用户ID为整数类型,生成JWT时存入payload的
user_id是整数 TokenData模型定义id: Optional[str],与实际传入的整数类型不匹配post.py中依赖注入错误,get_current_user返回的是TokenData对象,而非直接的整数ID
解决方案
方案1:修正TokenData的类型定义(推荐)
直接将TokenData的id类型改为整数,匹配数据库用户ID的类型:
# schemas.py from typing import Optional from pydantic import BaseModel class TokenData(BaseModel): id: Optional[int] # 将str改为int
方案2:将JWT payload中的ID转为字符串
如果坚持使用字符串类型ID,在解析JWT payload时将整数ID转为字符串:
# oauth2.py 中的 verify_access_token 函数 def verify_access_token(token: str, credentials_exception): try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) id: str = str(payload.get("user_id")) # 强制转为字符串 if id is None: raise credentials_exception token_data = schemas.TokenData(id=id) except JWTError: raise credentials_exception return token_data
修正post.py中的依赖注入错误
get_current_user返回的是TokenData对象,不能直接赋值给int类型的user_id,需要调整参数并关联用户ID到帖子:
# post.py @router.post("/", status_code=status.HTTP_201_CREATED, response_model=schemas.Post) def create_post( post: schemas.PostCreate, db: Session = Depends(get_db), current_user: schemas.TokenData = Depends(oauth2.get_current_user) # 修改参数类型 ): print(current_user.id) # 添加owner_id关联当前用户,确保帖子与创建者绑定 new_post = models.Post(owner_id=current_user.id, **post.model_dump()) db.add(new_post) db.commit() db.refresh(new_post) return new_post
额外检查
确保登录接口生成JWT时,传入的user_id是正确的用户ID(整数类型),示例代码如下:
# 登录接口示例 def login(user_credentials: schemas.UserLogin, db: Session = Depends(get_db)): user = db.query(models.User).filter(models.User.email == user_credentials.email).first() # ... 密码验证逻辑 ... access_token = oauth2.create_access_token(data={"user_id": user.id}) # user.id为整数类型 return {"access_token": access_token, "token_type": "bearer"}
内容的提问来源于stack exchange,提问作者JanLodewijk
相关产品推荐
相关产品推荐

