首页 > 其他分享 >flask搭建平台入门教程三:增删改查接口及权限校验(前后端分离)

flask搭建平台入门教程三:增删改查接口及权限校验(前后端分离)

时间:2022-10-16 20:33:31浏览次数:63  
标签:parser args flask fields 入门教程 改查 required add id

用户注册登录实现后,下一步编写查询用户列表接口,使用flask_restful的marshal方法来生成字段数据,加上之前编写的login_required

from flask import Blueprint,jsonify
from flask_restful import fields, marshal
from auth import login_required
from models.user import User

userbp = Blueprint('user',__name__,url_prefix="/user")

user_fields = {
    'id': fields.Integer,
    'username': fields.String,
    'nickname': fields.String,
    'email': fields.String,
    'group_id': fields.Integer,
    '_create_time': fields.DateTime(dt_format='iso8601'),
    'update_time': fields.DateTime(dt_format='iso8601'),
}

@userbp.route("/list",methods=['GET'])
@login_required
def list():
    users = User.getall()
    return jsonify(code=201,msg="操作成功",data=marshal(users, user_fields))

请求时header中不加入Authorization字段就会验证失败

在header中添加Authorization,值为Bearer+空格+login返回数据的access_token,成功获取list接口数据

用户的增删改查都是一样的逻辑来写

from flask import Blueprint, jsonify
from flask_restful import fields, marshal, reqparse
from werkzeug.security import generate_password_hash

from auth import login_required
from models.user import User

userbp = Blueprint('user',__name__,url_prefix="/user")

user_fields = {
    'id': fields.Integer,
    'username': fields.String,
    'nickname': fields.String,
    'email': fields.String,
    'group_id': fields.Integer,
    '_create_time': fields.DateTime(dt_format='iso8601'),
    'update_time': fields.DateTime(dt_format='iso8601'),
}

@userbp.route("/list",methods=['GET'])
@login_required
def list():
    users = User.getall()
    return jsonify(code=201,msg="操作成功",data=marshal(users, user_fields))

@userbp.route("/<uid>",methods=['GET'])
@login_required
def info(uid):
    user = User.getone(uid)
    return jsonify({
        "code": 0,
        "msg": "success",
        "data": marshal(user, user_fields)
    })

@userbp.route("/add",methods=['POST'])
@login_required
def add():
    parser = reqparse.RequestParser()
    parser.add_argument("username", type=str, required=True, help="username is required")
    parser.add_argument("nickname", type=str, required=True, help="nickname is required")
    parser.add_argument('password', required=True, type=str, help='password is required')
    parser.add_argument('email', required=False, type=str)
    parser.add_argument('group_id', required=False, type=int, default=2)
    args = parser.parse_args()
    if User.exist(username=args['username']):
        return jsonify(code=400,msg="用户名已存在")
    args.update({'password': generate_password_hash(args['password'], salt_length=8)})
    User.add(args)
    return jsonify(code=201,msg="添加成功")

@userbp.route("/edit",methods=['POST'])
@login_required
def edit():
    parser = reqparse.RequestParser()
    parser.add_argument("id", required=True, type=int, help="id is required")
    parser.add_argument("username", type=str, required=True, help="username is required")
    parser.add_argument("nickname", type=str, required=True, help="nickname is required")
    parser.add_argument('email', required=False, type=str)
    parser.add_argument('group_id', required=False, type=int)
    args = parser.parse_args()
    if not User.exist(id=args['id']):
        return jsonify(code=201,msg="用户不存在")
    User.edit(args)
    return jsonify(code=201,msg="修改成功")

@userbp.route("/delete",methods=['GET'])
@login_required
def delete():
    parser = reqparse.RequestParser()
    parser.add_argument("id", required=True, type=int, location='args',help="id is required")
    args = parser.parse_args()
    if not User.exist(id=args['id']):
        return jsonify(code=201,msg="用户不存在")
    User.remove(args['id'])
    return jsonify(code=201, msg="删除成功")

自定义权限校验

之后为接口添加分组的权限校验,根目录添加文件router.py,编写路由装饰器

routes ={}

def route_meta(auth,endname):
# endname必须是{Blueprint注册的名字.方法名} def wrapper(func): routes.setdefault(f"{endname}", auth) return func return wrapper

在auth.py添加校验路由的装饰器

def group_required(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
        if not current_user.isadmin:
            auth = routes.get(request.endpoint)
            groupid = current_user.group_id
            authed = Auth.exist(group_id=groupid,auth=auth,endpoint=request.endpoint)
            if not authed:
                return jsonify(code=10000,msg="权限不够,请联系超级管理员获得权限")
            return fn(*args,**kwargs)
        else:
            return fn(*args,**kwargs)
    return wrapper

在add接口方法加上这两个装饰器,route_meta第二个参数必须是{Blueprint注册的名字.方法名}

@route_meta("新增用户", "user.add")
@userview.route("/add",methods=['POST'])
@login_required
@group_required
def add():
  ......

再次请求add接口会提示没有权限

{ "code": 10000, "msg": "权限不够,请联系超级管理员获得权限" }   之后就需要为用户添加权限,权限关联到相关分组,所以添加修改分组接口
@groupbp.route("/edit",methods=['POST'])
@login_required
def edit():
    parser = reqparse.RequestParser()
    parser.add_argument("id", required=True, type=int, help="id is required")
    parser.add_argument("name", required=True, type=str,  help="name is required")
    parser.add_argument("info", required=False, type=str)
    args = parser.parse_args()
    args['auths'] = request.json['auths']
    sql = select(Group).where(Group.name==args['name'],Group.id!=args['id'])
    if db.session.execute(sql).first():
        return jsonify(code=10000,msg="分组名已存在")
    Group.edit(args) # 需要重写edit
    return jsonify(code=201,msg="操作成功")

由于修改分组需要添加、删除auth表的数据,所以要在models/group.py文件增加自己的edit方法

from models.auth import Auth

class Group:
......

@classmethod def edit(cls, data): group = cls.getone(data['id']) group.name = data['name'] group.info = data['info'] for auth in group.auths: Auth.remove(auth.id) for item in data.get('auths'): authobj = Auth.add(dict(endpoint=item,auth=routes[item])) group.auths.append(authobj) db.session.commit()

 

通过group/edit接口可以为admin分组增加权限

 

上面接口成功的话就为admin增加了add和edit这两个方法的权限,再添加和修改用户就能成功了

{ "code": 201, "msg": "添加成功" }   其它用户登录操作add、edit则会提示权限不够,当为delete方法添加group_required装饰器后,admin删除用户也会提示权限不够   至此flask用户管理及权限验证的后台接口基本后端框架就完成了,还有一些细节需要自己去改进,然后就是选择前端框架编写前端页面。

 

标签:parser,args,flask,fields,入门教程,改查,required,add,id
From: https://www.cnblogs.com/zerotest/p/16797023.html

相关文章

  • flask搭建平台入门教程二:用户注册和登录
    这一篇主要实现用户注册和登录编写接口并设置URL根目录添加api文件夹,添加auth.py注册auth蓝图为根路径fromflaskimportBlueprint,jsonifyauthbp=Blueprint('au......
  • flask搭建平台入门教程一:配置数据库
    flask是什么?flask可以做什么这里就不说了,百度一下即可,这篇文章主要是手把手带你使用flask搭建一个简单的注册、登陆、以及用户权限管理模块。首先需要创建一个FLASK项......
  • flask-信号
    flask信号Flask框架中的信号基于blinker,其主要就是让开发者可是在flask请求过程中定制一些用户行为。#pip3installblinker1.内置信号request_started=_signals......
  • Flask 学习-91.使用 gunicorn 部署 flask
    前言flask启动访问平常开发的时候可以用命令行flaskrun运行,正式部署到线上环境不会这样用。Gunicorn环境准备Web框架致力于如何生成HTML代码,而Web服务器用于处理和响......
  • 用flask搭建管理平台
    flask是什么?flask可以做什么这里就不说了,百度一下即可,这篇文章主要是手把手带你使用flask搭建一个简单的注册、登陆、以及用户权限管理模块。在pycharm上创建新的flask......
  • Python Flask-SocketIO没有启动成功
    背景最近想做websocket服务端,发现Flask已提供第三方库;尝试使用后,发现前端也必须使用SocketIO,不太适用,所以放弃。 问题WARNINGininit:WebSockettransportnotavai......
  • Python Flask 返回html文件
    1、在templates文件夹建立一个html文件<!DOCTYPE html><html><head>    <meta charset="UTF-8">    <title>Index</title></head><body><h2>This is i......
  • Python Flask报错:TypeError: 'NoneType' object is not subscriptable
    问题:用Flask写了一个请求,用Jmeter请求时报错;但在postman中参数发送,可以成功返回数据以及正常状态码200; 分析:request以json形式发送post请求时,需要headers 解决:he......
  • Python 第一个Flask
    安装flaskpip3installflask 导入类fromflaskimportFlask 第一个Flask实例化创建一个Flask应用,第一个参数是Flask应用的名称app=Flask(__name_......
  • Python Flask HTTP请求
    GET请求@app.route('/get',methods=["GET"])defget_():#返回字符串return'这是get请求' POST请求@app.route('/post',methods=["POST"])defpost......