Skip to content

用户登录

用户登录

I.请求与响应过程

flowchart  LR

    subgraph B [后端]
        U[FastAPI服务]
    end

    subgraph A [用户界面]
        direction LR
        F1[用户登录]
    end

   A -- ① 请求分类<br> /api/user/login --> B
   B -- ② 返回响应 <br> {'code': 200,'message': 'success','token':用户令牌',data': [{'id': 1,'username': 用户名}]}  -->  A

image-20251025130818007

II. 数据校验模型

在进行用户登录时,也需要对传递的数据进行校验。

当前场景下和注册验证字段一样,后续项目注册时可能还会携带携带其他信息字段,所以注册和登录验证的字段会有不同,建议分开定义。

users.py文件

class UserLoginRequest(BaseModel):
    """
    用户登录请求数据模型
    """
    username: str  # 用户名,必填
    password: str  # 密码,必填

    class Config:
        schema_extra = {
            "example": {
                "username": "example_user",
                "password": "example_password"
            }
        }

image-20251025131703638

III. 路由定义

users.py文件,编写路由解析代码

注意:登录时需要使用post

@router.post("/login")
async def login_user(
        login_data: UserLoginRequest,
        db: AsyncSession = Depends(get_db)
):
    """
    用户登录接口

    Args:
        login_data: 用户登录请求数据
        db: 数据库会话

    Returns:
        UserLoginResponse: 登录成功响应
    """
    # 验证用户身份


    # 返回成功响应
    return {
        'code':200,
        'message':"登录成功",
        "data":'登录功能'
    }

image-20251025131944382

main.py文件中已经进行路由注册,无需再注册路由

重启FastAPI服务,运行测试,检查定义的路由接口是否能够处理前端发送的请求

post请求可以借助http工具

1
2
3
4
5
6
7
8
### 用户登录
POST http://127.0.0.1:8000/api/user/login
Content-Type: application/json

{
  "username": "test123",
  "password": "123456"
}

image-20251025132123633

IV. 定义模型类

用户模型类在注册时已经完成,无需再定义

V. 编写ORM数据操作

users.py文件

主要实现以下功能:

  • 对混淆后的密码验证
  • 验证用户名
## ................
## 其他代码
## ................

def verify_password(plain_password: str, hashed_password: str) -> bool:
    """
    验证明文密码与哈希密码是否匹配

    Args:
        plain_password: 明文密码
        hashed_password: 哈希密码

    Returns:
        bool: 密码是否匹配
    """
    return pwd_context.verify(plain_password, hashed_password)

async def authenticate_user(db: AsyncSession, username: str, password: str) -> User:
    """
    验证用户身份

    Args:
        db: 数据库会话
        username: 用户名
        password: 明文密码

    Returns:
        User: 验证成功的用户对象,验证失败返回None
    """
    user = await get_user_by_username(db, username)
    if not user:
        return None
    if not verify_password(password, user.password):
        return None
    return user

image-20251025132725123

VI. 路由中实现数据操作

回到对应的路由中,调用刚才编写好的数据处理函数。

@router.post("/login")
async def login_user(
        login_data: UserLoginRequest,
        db: AsyncSession = Depends(get_db)
):
    """
    用户登录接口

    Args:
        login_data: 用户登录请求数据
        db: 数据库会话

    Returns:
        UserLoginResponse: 登录成功响应
    """
    # 验证用户身份
    user = await users.authenticate_user(db, login_data.username, login_data.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户名或密码错误"
        )

    # 创建访问令牌
    token = await users.create_user_token(db, user.id)

    # 返回成功响应
    return {
        'code':200,
        'message':"登录成功",
        "data":{
            "token": token,
            "userInfo": {
                "id": user.id,
                "username": user.username,
                "nickname": user.nickname,
                "avatar": user.avatar,
                "bio": user.bio
            }
        }
    }

重启FastAPI服务,测试数据是否正常返回

image-20251025133039739

启动前端服务检查数据是否正常加载,登录成功后会自动跳转首页

image-20251025133123522

image-20251025133145995

image-20251025130541274

VII. 退出登录

当用户点击退出登录后,前端会自动清除token信息,此时相当于没有了用户的身份标识,等价于退出登录了。后端无需再进行其他操作