当前位置:   article > 正文

FastAPI Web框架教程 第9章 登录认证相关_fastapi 登录验证

fastapi 登录验证

9-1 用户注册

需求场景

对于很多应用来说,注册接口是必可不少的。想要实现注册接口,其实很简单,但是你会发现会有很多种选择:

  • 注册时有需要哪些字段?
  • 注册接口使用什么请求方式?
  • 前端朝后端传数据时,放在查询参数中、请求体中?
  • 如果放在请求体中,使用JSON格式还是表单格式?

解决方式

你会发现就一个简单的注册接口,其实还是有很多问题需要我们思考的。

首先,注册接口一般是将用户的个人信息提交给服务端,因此,我们选择POST请求

然后,注册信息中一般都包含密码,所以不能简单的在查询参数中提交给后端,需要把数据放在请求体中。

最后,请求体如何使用JSON格式,那注册时如果有上传文件的需求,将比较麻烦。因此我们使用Form表单的形式。

结论:对于常见的注册接口,使用POST,使用Form表单来上传数据。

补充:任何一种方式都可以实现,但最终如何选择还是要看业务需求。

前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h1>注册</h1>
<form action="http://127.0.0.1:8000/register" method="post" enctype="multipart/form-data">
    <p>用户名: <input type="text" name="username"></p>
    <p>密码: <input type="password" name="password"></p>
    <p>确认密码: <input type="password" name="re_password"></p>
    <p>邮件: <input type="email" name="email"></p>
    <p><input type="submit"></p>
    
</form>

</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

后端接口

  • 注册逻辑:判断用户名是否已经注册;判断二次密码是否一致。
  • 缺陷:密码没有加密;数据没有持久化(存数据库)。
from fastapi import FastAPI, Form, Depends, HTTPException

app = FastAPI(title="登录认证相关")


# 模拟数据库
USERS = {
   }


def get_form_data(username: str = Form(), password: str = Form(), re_password: str = Form(), email: str = Form()):
    return {
   
        "username": username,
        "password": password,
        "re_password": re_password,
        "email": email,
    }


@app.post("/register")
def register(form_data: dict = Depends(get_form_data)):
    # 判断用户名是否已存在
    if form_data["username"] in USERS:
        raise HTTPException(detail="用户名已经存在", status_code=400)
    # 判断密码是否一致
    if form_data["password"] != form_data["re_password"]:
        raise HTTPException(detail="两次密码输入不一致", status_code=400)
    # 保存用户信息,完成注册
    USERS[form_data["username"]] = form_data

    # 返回新用户基本信息
    return {
   "username": form_data["username"], "email": form_data["email"]}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

9-2 用户密码加密

存用户信息时,不能明文存储,一定要做加密处理。

示例1: 使用python内置库hasslib

import hashlib


m = hashlib.md5("盐".encode("utf-8"))	# 支持加盐
m.update("hello".encode("utf-8"))

print(m.digest())       # 加密后的二进制文本
print(m.hexdigest())    # 以16进制形式返回加密内容
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

示例2:使用第三方库 passlib

pip install “passlib[bcrypt]”

from passlib.context import CryptContext

crypt = CryptContext(schemes=["bcrypt"], deprecated="auto")

crypt.hash("hello")		# 加密
  • 1
  • 2
  • 3
  • 4
  • 5

9-3 集成MySQL的注册

需求场景

上节课,我们实现了注册页面和注册接口,但是有明显的缺陷,比如说密码没有加密,数据没有存数据库。

解决方式

第一步:数据持久化

  • 新建用户表
CREATE TABLE `users` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(255) NOT NULL,
    `password` varchar(255) NOT NULL,
    `email` varchar(255) NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=1 ;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 使用SQLAlchemy的ORM操作数据库(基于8-13节代码结构,其他模块代码见源文件)
from fastapi import FastAPI, Form, Depends, HTTPException
from sqlalchemy.orm import Session
from passlib.context import CryptContext

from database import get_db
from models import User
from schemas import UserOut

app = FastAPI(title="登录认证相关")


crypt = CryptContext(schemes=["bcrypt"], deprecated="auto")


class UserForm:
    def __init__(
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/912063
推荐阅读
相关标签
  

闽ICP备14008679号