使用fastzdp_sqlmodel改造fastzdp_login中关于用户注册和用户登录的接口

news2024/11/15 23:55:58

原本的代码

@user_router.post("/register/", summary="用户注册")
def register_user(
        username: str = Body(str, min_length=2, max_length=36),
        password: str = Body(str, min_length=6, max_length=128),
        db: SASession = Depends(get_db),
):
    # 检查用户名是否已存在
    user = db.exec(select(FastZdpUserModel).where(FastZdpUserModel.username == username)).first()
    if user:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户名已存在")

    # 创建新用户
    new_user = FastZdpUserModel(username=username, password=hash_256(password))
    db.add(new_user)
    try:
        db.commit()
        db.refresh(new_user)
    except Exception as e:
        print(e)
        db.rollback()
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户注册失败")

    return {"message": "用户注册成功", "user_id": new_user.id}

说明

在fastzdp_sqlmodel基本封装完毕以后,我就决定将其应用到实战中,因为只有经过实际项目的考研,才能够说明框架的稳定性,也更能够在实际使用的过程中发现框架可能存在的一些问题。

原本的入口代码分析

import fastzdp_login
from fastapi import FastAPI
from sqlmodel import SQLModel, Session, create_engine

# 创建数据库引擎
sqlite_url = "mysql+pymysql://root:root@127.0.0.1:3306/fastzdp_login?charset=utf8mb4"
engine = create_engine(sqlite_url, echo=True)

# 确保表存在
SQLModel.metadata.drop_all(engine)
SQLModel.metadata.create_all(engine)

app = FastAPI()

# 伪造一个密钥,实际使用时应该使用安全的方式存储
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"

# 令牌有效期
ACCESS_TOKEN_EXPIRE_MINUTES = 30


def get_db():
    db = Session(engine)
    try:
        yield db
    finally:
        db.close()


app.include_router(fastzdp_login.get_user_router(
    get_db,
    SECRET_KEY,
    ALGORITHM,
    ACCESS_TOKEN_EXPIRE_MINUTES * 60
))

if __name__ == '__main__':
    import uvicorn

    uvicorn.run(app, host='0.0.0.0', port=8888)

在这个代码里面,我们需要手动的将get_db方法传递进去,如果使用fastzdp_sqlmodel的话,就只需要传递engine进去就行了。

我们来试试

初步改造如下

@user_router.post("/register/", summary="用户注册")
def register_user(
        username: str = Body(str, min_length=2, max_length=36),
        password: str = Body(str, min_length=6, max_length=128),
):
    # 检查用户名是否已存在
    users = fs.get_by_dict(engine, FastZdpUserModel, {"username": username})
    if users and len(users) > 0:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户名已存在")

    # 创建新用户
    new_user = FastZdpUserModel(username=username, password=hash_256(password))
    fs.add(engine, new_user)
    return {}

只不过目前还不能直接测试,因为用户登录接口还没有改造完毕。

接下来,我们继续改造用户登录的接口。

原来的用户登录接口

@user_router.post("/login/", summary="用户登录")
async def login_for_access_token(
        username: str = Body(str, min_length=2, max_length=36),
        password: str = Body(str, min_length=6, max_length=128),
        db: SASession = Depends(get_db),
):
    user = db.exec(select(FastZdpUserModel).where(FastZdpUserModel.username == username)).first()
    if not user:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户名或密码错误")
    if not verify_256(password, user.password):
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户名或密码错误")
    data = {"username": user.username, "id": user.id, "time": time.time(),
            "expired": jwt_token_expired}
    access_token = get_jwt(data, jwt_key, jwt_algorithm)
    return {"access_token": access_token, "token_type": "bearer"}

改造后的用户登录接口

@user_router.post("/login/", summary="用户登录")
async def login_for_access_token(
        username: str = Body(str, min_length=2, max_length=36),
        password: str = Body(str, min_length=6, max_length=128),
):
    # 查找
    users = fs.get_by_dict(engine, FastZdpUserModel, {"username": username})
    if not users or len(users) == 0:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户名或密码错误")

    # 校验密码
    user = users[0]
    if not verify_256(password, user.password):
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户名或密码错误")

    # 生成Token
    data = {
        "username": user.username,
        "id": user.id,
        "time": time.time(),
        "expired": jwt_token_expired,
    }
    access_token = get_jwt(data, jwt_key, jwt_algorithm)

    # 返回
    return {"access_token": access_token, "token_type": "bearer"}

改造入口代码

import fastzdp_login
from fastapi import FastAPI
from sqlmodel import SQLModel, Session, create_engine

# 创建数据库引擎
sqlite_url = "mysql+pymysql://root:root@127.0.0.1:3306/fastzdp_login?charset=utf8mb4"
engine = create_engine(sqlite_url, echo=True)

# 确保表存在
SQLModel.metadata.drop_all(engine)
SQLModel.metadata.create_all(engine)

app = FastAPI()

# 伪造一个密钥,实际使用时应该使用安全的方式存储
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"

# 令牌有效期
ACCESS_TOKEN_EXPIRE_MINUTES = 30

app.include_router(fastzdp_login.get_user_router(
    engine,
    SECRET_KEY,
    ALGORITHM,
    ACCESS_TOKEN_EXPIRE_MINUTES * 60
))

if __name__ == '__main__':
    import uvicorn

    uvicorn.run(app, host='0.0.0.0', port=8888)

通过接口文档测试

启动入口代码,访问接口问题。

比较遗憾的是FastAPI自带的接口文档并不稳定,比如今天就碰到了无法访问的问题。

在这里插入图片描述

所以我决定使用自己开发的req工具进行接口测试。

测试注册接口:

req -X POST -H 'Content-Type:application/json' -d '{\"username\":\"zhangdapeng\",\"password\":\"zhangdapeng520\"}' http://127.0.0.1:8888/fastzdp_login/register/

在这里插入图片描述

可以发现,返回的状态码是200,说明注册成功了。
在这里插入图片描述

测试登录接口:

req -X POST -H 'Content-Type:application/json' -d '{\"username\":\"zhangdapeng\",\"password\":\"zhangdapeng520\"}' http://127.0.0.1:8888/fastzdp_login/login/

成功的登录并获取到了JWT Token。
在这里插入图片描述

总结

本篇教程主要记录了fastzdp_login通过整合fastzdp_sqlmodel实现版本升级的的详细过程。

升级以后,功能并没有太大的变化,只是底层使用的技术发生了改变。

通过本次实战,也发现了fastzdp_sqlmodel还缺少两个便捷的方法。

  • is_exists:用来判断是否存在某条数据
  • get_first:获取一条数据

后续我还会继续升级fastzdp_sqlmodel这个框架,敬请关注。

如果你需要本教程的完整源码,或者需要完整的零基础到实战的FastAPI实战录播课,或者需要一对一的私教指导,欢迎留言或者私信我。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2050082.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

家政服务管理系统小程序的设计

管理员账户功能包括:系统首页,个人中心,用户管理,管理阿姨管理,家政公司管理,服务项目管理,家政预约管理,评价管理,留言板管理,系统管理 微信端账号功能包括…

【串口助手开发】添加保存数据功能,按钮按下保存接收区所有数据

1、功能描述 想要将串口助手接收区域内所有的内容保存下来 并且通过按钮,按下后,跳出一个弹窗,显示保存路径,并且保存txt文件 按下按钮,保存txt数据文件。 2、代码讲解 定义一个全局变量,接收所有的数…

STM32第十二节(中级篇):串口通信(第二节)——串口固件库函数以及串口发送和接收代码讲解

STM32第十二节(中级篇):串口通信(第二节)——串口固件库函数以及串口发送和接收代码讲解 串口固件库函数 代码片段 /** * brief USART Init Structure definition */ typedef struct {uint32_t USART_BaudRate; …

1.初识算法

1.1 算法无处不在 当我们听到“算法”这个词时,很自然地会想到数学。然而实际上,许多算法并不涉及复杂数学,而是更多地依赖基本逻辑,这些逻辑在我们的日常生活中处处可见。 在正式探讨算法之前,有一个有趣的事实值…

科研单位所需要的文件自动同步备份软件具有哪些特征?

科研单位进行文件同步备份是保障数据安全、提高工作效率、符合法规要求以及实现数据共享与再利用的重要措施。文件同步备份不仅能保护科研单位的研究成果,还能提升工作协同效率,具体优势体现在: 预防数据丢失:科研单位在工作中会产…

还不了解 Pinia 状态管理库⁉️

还不了解 Pinia 状态管理库⁉️🍍 什么是Pinia❓状态管理工具⁉️: 学习过Vue2的小伙伴,一定都知道Vuex,什么不知道,请看VCR👉 ; Vuex 是一个专为 Vue.js 应用程序设计的状态管理库&#xff0…

什么是GD32 MCU读保护?

如今电子产品市场风云变幻,暗流汹涌,有没有小伙伴遇到自己费了大力气写出来的代码,很容易就被别人“借鉴”了,真的是让闻者伤心,听着落泪啊。 那有没有什么方法可以防止别人将你的代码从MCU读出来呢?答案当…

软媒市场-解释软文发布后如何在搜索引擎持续获得曝光

软文发布后,在搜索引擎持续获得曝光是一个涉及多方面策略的过程。以下是一些关键步骤和技巧,旨在帮助软文在搜索引擎中保持较高的可见度和曝光率: 1. 关键词优化 关键词选择:首先,通过专业的关键词研究工具(如Google AdWords Keyword Planner、百度指数等)分析用户搜索习惯和热…

【C语言初阶】掌握C语言调试技巧,迈向高效编程的阶梯

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C语言 “ 登神长阶 ” 🤡往期回顾🤡:C语言指针 🌹🌹期待您的关注 🌹🌹 ❀C语言调试技巧 📒1. …

这个是git使用的合集

如果遇到了关于git和github的bug就会写这里 2024/8/16 github一直没有打卡和上传代码是因为感觉除了做项目的情况,普通的学习和普通的笔记没必要记在github里;如果是笔记类的东西为什么不记在csdn上呢?如果是算法题算法网站上回有记录啊&am…

第43课 Scratch入门篇:雪花随风飘

雪花随风飘 故事背景: 雪花轻轻地从灰蒙蒙的天空中飘落下来,它们像是天空中飘洒下来的羽毛,又像是冬日的精灵在翩翩起舞。每一片雪花都独一无二,它们在空中旋转、飘荡,最终缓缓降落在屋顶、树枝、街道和行人的肩头。 程序原理: 众多的雪花肯定是克隆功能,降落过程是通过…

three.js 光源、光源辅助对象和阴影简介

Three.js 光源对物体的影响 实际生活中物体表面的明暗效果是会受到光照的影响,比如晚上不开灯,你就看不到物体,灯光比较暗,物体也比较暗。在threejs中,咱们用网格模型Mesh模拟生活中物体,所以threejs中模拟…

Linux进程间通信学习记录(IPC 机制以及共享内存)

0.System V IPC机制: ①.IPC对象包含:共享内存、消息队列和信号灯集。 ②.每个IPC对象有唯一的ID。 ③.IPC对象创建后一直存在,直到被显示地删除。 ④.每一个IPC对象有一个关联的KEY。(其他进程通过KEY访问对应的IPC对象&#xff…

索引的设计原则

4.索引的设计原则 4.1.数据准备 a.创建数据库、创建表 CREATE DATABASE atguigudb1; USE atguigudb1;# 创建学生表和课程表 CREATE TABLE student_info (id INT(11) AUTO_INCREMENT,student_id INT NOT NULL ,name VARCHAR(20) DEFAULT NULL,course_id INT NOT NULL ,class_…

x64汇编语言与逆向工程实战指南(四)

目录 1. 数组的存储与遍历1.1 编写数组数据写入内存1.2 汇编循环遍历数组元素 3. Lea指令4. mul指令与imul指令4.1 mul 指令4.2 imul 指令总结 5. div指令5.1 div 指令的基本原理5.2 8 位除法5.3 16 位除法5.3 32 位除法特点和要求 1. 数组的存储与遍历 1.1 编写数组数据写入内…

基于Web的可回收物品收购系统-计算机毕业设计源码49082

摘 要 随着电子商务和在线交易的快速发展,二手商品市场逐渐成为一个不可忽视的经济领域。其中,可回收系统的收购成为了一个关键环节,它不仅有助于资源的有效再利用,还对环境保护和可持续发展起到了积极的推动作用。Servlet可回收…

单片机中的存储器讲解

单片机中的存储器 目录 单片机中的存储器常用的存储器易失性存储器RAMSRAMDRAM 非易失性存储器ROMMask ROMPROMEPROME2PROMFlashNOR FlashNADN Flash 单片机里全局变量、局部变量、堆、栈的存储区域区域介绍栈区堆区静态区代码区常量区 内存分区分类四个区域 常用的存储器 易失…

【Linux】:实现一个简易的shell

目录 1.命令行提示符 2.命令行参数 2.1 获取命令行参数 2.2 解析命令行参数 3.判断指令类型 3.1 模拟cd命令 3.2 模拟export和echo bash的环境变量来源 4.外部指令的执行 1.命令行提示符 在我们输入指令前,终端界面一般有一个命令行提示符, …

性能优化理论篇 | swap area是个什么东西

我们知道每台计算机的内存(RAM)都是有限的,而我们的应用程序需要加载到内存才能被运行,如果一台机器运行多个应用程序时,内存可能会耗尽。Linux 系统中的“交换空间(也称为交换分区)”可以帮助缓…

VM相关配置及docker

NAT——VMnet8网卡 桥接——WLAN/网线 仅主机——VMnet1网卡 docker与虚拟机的区别 启动docker服务 systemctl start docker 重启 systemctl start docker关闭docker服务 systemctl stop docker.servicedocker的两大概念 镜像:images,应用程序的静态文…