使用 Sqlalchemy 的带有 JWT 令牌生成错误的 OAuth2

OAuth2 with JWT tokens generation error using Sqlalchemy

我是 FastApi 的初学者,我正在尝试 FastApi tutorial for SQL 使用 OAuth 身份验证。到目前为止,我已经设法为使用密码散列的用户创建了 crud。但是,现在我正在尝试在用户尝试登录时使用 JWT 令牌生成功能,但我对如何替换实际的 PostgresSQL 数据库而不是教程中给定的 fake_database 示例感到困惑。我尝试用 db: Session 替换 fake_database 但现在出现此错误。

sqlalchemy.orm.exc.UnmappedInstanceError: Class 'builtins.str' is not mapped

main.py 文件

@app.post("/token", response_model=schemas.Token)
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)):
    user = crud.authenticate_user(db, form_data.username, form_data.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = crud.create_access_token(
        data={"sub": user.username}, expires_delta=access_token_expires
    )
    return {"access_token": access_token, "token_type": "bearer"}

crud.py 文件

def authenticate_user(db: Session, username: str, password: str):
    user = get_user_for_authentication(db, username)
    if not user:
        return False
    if not verify_password(password, user.password):
        return False
    return user


def get_user_for_authentication(db: Session, username: str):
    if username in db:
        user_dict = db[username]
        return schemas.UserInDB(**user_dict)

schemas.py 文件

from typing import List, Optional
from pydantic import BaseModel

class UserBase(BaseModel):
    username: str
    name: Optional[str] = None
    email: Optional[str] = None

class User(UserBase):
    id: int
    is_active: bool
    items: List[Item] = []

    class Config:
        orm_mode = True

class UserInDB(UserBase):
    password: str

class UserCreate(UserBase):
    password: str

class Token(BaseModel):
    access_token: str
    token_type: str
    
class TokenData(BaseModel):
    username: Optional[str] = None

我做错了什么?任何帮助将不胜感激!

由于您现在正在发送实际的数据库会话,因此您需要像使用常规 sqlalchemy 方法一样查询数据库。

错误信息是由以下原因引起的:

if username in db:

它会尝试检查 str 是否在当前数据库会话中 - 这不会起作用,因为它旨在检查给定返回的 SQLAlchemy 对象是否已存在于当前数据库会话中。

您可以将其替换为:

db.query(UserModel).filter(UserModel.username == username).first()

取决于您在 SQLAlchemy 中的用户模型的结构。