注册联调:
前端修改:
 1.修改请求向后端的url地址
 文件:env.development修改成VITE_API_TARGET_URL= http://127.0.0.1:9000/v1
登录:token验证
校验forms/user.py
from werkzeug.security import check_password_hash
# 登录校验
class Loginform(Form):
    username = StringField(validators=[DataRequired()])
    password = StringField(validators=[DataRequired(), Regexp(r'\w{6,18}', message="密码不符合要求")])
    def validate(self):
        super().validate()
        if self.errors:
            return False
        user = User.query.filter_by(username = self.username.data).first()
        if user and check_password_hash(user.password, self.password.data):
            return user
        else:
            raise ValidationError("验证失败!")
router/user/user.py
from libs.auth import create_token
# 登录视图
class LoginView(Resource):
    def post(self):
        data = request.json
        form = LoginForm(data = data)
        user = form.validate()
        if user:
            return generate_response(msg="login success!", code=0)
        else:
            return generate_response(msg="login fail!", code=1)
api.add_resource(LoginView, "/login")
在config里写好secretkey和过期时间
# 内部私钥
SECRET_KEY = "123456"
# 过期时间
EXPIRES_IN = "10"
libs/auth.py生成token函数放这里
from flask import current_app
from itsdangerous import TimedSerializer
# 生成token
def create_token(uid):
    # 生成token,第一个参数传入内部私钥,第二个参数有效期
    s = TimedSerializer(current_app.config["SECRET_KEY"], current_app.config["EXPIRES_IN"])
    token = s.dumps({"uid":uid})
    return token

 每次请求的token都不一样
pyjwt是web开发里专门用来生成token的库
 pip install pyjwt
 libs/auth.py
import jwt
from jwt.exceptions import ExpiredSignatureError, InvalidSignatureError
#用jwt生成token库
def create_token(uid):
    expir_in = current_app.config.get("EXPIRES_IN")
    payload = {"uid":uid, "exp":time.time() + expir_in}
    print(payload)
    key = current_app.config["SECRET_KEY"]
    token = jwt.encode(payload, key)
    return token
过期时间改回整形config/settings.py
# 过期时间
EXPIRES_IN = 600

 这个token是base64加密
{
    "code": 0,
    "msg": "login success!",
    "data": {
        "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjMsImV4cCI6MTY5NDkzMjIyOS4zNDM5MTF9.03zt-xxAvgJ487Hwfk3nyCa-vq0ml3kPcEo3SDT-UOc",
        "username": "jd2"
    }
}
Header
 Payload
 {“alg”:“HS256”,“typ”:“JWT”}{“uid”:3,“exp”:1694932229.343911}
Signature
 为了得到签名部分,你必须有编码过的header、编码过的payload、一个秘钥,签名算法是header中指定的那个,然对它们签名即可。
 例如:
HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret)
服务端验证:拿到token之后,按照里面的header+payload+服务端保存的secretkey一起进行相同算法加密。得到新的签名,再和客户端传递的签名比较,一致就验证通过
两种验证:api验证,token验证
 #验证token
 libs/auth.py
def auth_required(func):
    def inner(*args, **kwargs):
        api_flag = request.args.get("api")
        if (api_flag == "1" and api_auth()) or token_auth():
            return func(*args, **kwargs)
        else:
            return "认证失败"
    return inner
# 验证token
def token_auth():
    token = request.headers.get("token")
    if token:
        try:
            print(time.time())
            jwt_obj = jwt.decode(token, current_app.config.get("SECRET_KEY"),
                                 algorithms=["HS256"])
        except InvalidSignatureError as e:
            print("token不合法", e)
            return False
        except ExpiredSignatureError as e:
            print("token过期", e)
            return False
        return True
    else:
        return False
首先POST访问127.0.0.1:9000/v1/login
 得到token,复制粘贴,然后GET访问127.0.0.1:9000/v1/product,HEADERS中代token字段访问
 
 前后端联调
前端流程
异常标准化返回
 libs/error_code.py
from werkzeug.exceptions import HTTPException
class APIException(HTTPException):
    code = 500   #http状态码
    message = "fail!"  #状态描述信息
    status_code = 9999 # 程序状态
    def __init__(self, message=None, code=None, status_code = None):
        if message:
            self.message = message
        if code:
            self.code = code
        if status_code:
            self.status_code = status_code
        super(APIException, self).__init__()
    def get_body(self, environ = None, scope = None) -> str:
        body = dict(
            message = self.message,
            code = self.status_code
        )
        import json
        content = json.dumps(body)
        return content
    def get_headers(self, environ = None, scope = None,) :
        return [('content-Type', 'application/json')]
#自定义异常类
class APIAuthorizedException(APIException):
    message = "API授权认证失败"
    status_code = 10002
    code = 401
class FormValidateException(APIException):
    message = "表单验证失败"
    status_code = 10003
class TokenFailException(APIException):
    message = "token不合法,验证失败"
    status_code = 10005
    code = 401
libs/handler.py
from flask_restful import HTTPException
from libs.error_code import APIException
#无论什么异常  都返回APIException
def default_error_handler(ex):
    if isinstance(ex, APIException):
        return ex
    if isinstance(ex, HTTPException):
        code = ex.code
        message = ex.description
        status_code = 10001
        return APIException(code = code, message=message, status_code=status_code)
    return APIException()
from libs.handler import default_error_handler
#异常标准化返回
api.handle_error = default_error_handler
#异常标准化返回
 handle_error 原本处理异常情况返回的一个方法
 当发生异常情况时,会自动调用handle_error函数处理异常返回
 
 修改libs/auth.py
from libs.error_code import APIAuthorizedException
def auth_required(func):
    def inner(*args, **kwargs):
        api_flag = request.args.get("api")
        if (api_flag == "1" and api_auth()) or token_auth():
            return func(*args, **kwargs)
        else:
            raise APIAuthorizedException
    return inner

![[计组03]进程详解2](https://img-blog.csdnimg.cn/52f8c8819651498ab1aa04a227530e88.png)


















