当前位置: 首页 > article >正文

2.flask中使用装饰器统一验证用户登录

使用注意事项

1.装饰器函数注解要放到离被装饰函数最近的位置。

让请求一进来先执行装饰器,而不是原函数

2.必须使用@functools.wraps(func),否则所有被装饰的函数的名称都变成了inner,函数与url的绑定就重复了,无法识别。

from flask import Flask
import functools

app = Flask(__name__)


def auth(func):
    @functools.wraps(func)
    def inner(*args, **kwargs):
        func(*args, **kwargs)
    return inner


@app.route("/login")
@auth
def login():
    pass


if __name__ == '__main__':
    app.run()

对上一篇中用户登录验证功能采用装饰器进行优化

from flask import Flask, render_template, request, redirect, url_for, session
import functools
app = Flask(__name__, template_folder="templates")
# 使用session时需要,值可以先随便写一个
app.secret_key = "12345"

# 定义一个全局变量来当做数据库
DATA_DICT = {
    1: {'name': '张三', 'age': 18, 'gender': '男'},
    2: {'name': '李四', 'age': 22, 'gender': '男'}
}


def auth(func):
    """
    使用装饰器验证用户是否登录
    :param func:
    :return:
    """
    @functools.wraps(func)
    def inner(*args, **kwargs):
        username = session.get('xx')
        if not username:
            # 如果未登录则跳转到登录页面
            return redirect("/login")
        return func(*args, **kwargs)
    return inner


@app.route("/login", methods=["GET", "POST"])
def login():
    method = request.method
    if method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        if username == 'admin' and password == '123':
            session['xx'] = username
            return redirect("/index")
    error = '用户名密码错误'
    return render_template("login.html", error=error)


# endpoint给路由取了个别名,如果不指定,endpoint的默认值为函数名
# endpoint的值不能重名
@app.route("/index", endpoint="index_page")
@auth
def index():
    return render_template("index.html", DATA_DICT=DATA_DICT)


@app.route("/edit", methods=['GET', "POST"])
@auth
def edit():
    id = request.args.get('nid')
    id = int(id)
    if request.method == 'POST':
        name = request.form.get('name')
        age = request.form.get('age')
        gender = request.form.get('gender')
        DATA_DICT[id]['name'] = name
        DATA_DICT[id]['age'] = age
        DATA_DICT[id]['gender'] = gender
        return redirect(url_for("index_page"))
    info = DATA_DICT[id]
    return render_template("edit.html", info=info)


# 默认就是str类型,可以不写
@app.route("/del/<int:nid>")
@auth
def delete(nid):
    print(f"nid={nid}")
    # 根据key删除dict的元素
    del DATA_DICT[nid]
    # 通过url_for来重定向跳转
    return redirect("/index")


if __name__ == '__main__':
    app.run()

注意:

1.@auth一定要放在@app.route(“url”)下面,因为url要跟装饰函数建立关系。

2.装饰函数一定要使用@functools.wraps(func),保证每个函数的__name__是它自己的,而不是统一的inner,防止出现如下错误:

AssertionError: View function mapping is overwriting an existing endpoint function: inner


http://www.kler.cn/a/463172.html

相关文章:

  • 38. 考古学家
  • OpenNJet v3.2.0正式发布!
  • ubuntu支持ssh
  • TT100K数据集, YOLO格式, COCO格式
  • CentOS7安装配置JDK保姆级教程(图文详解)
  • TP8 前后端跨域访问请求API接口解决办法
  • npm install 安装选项 -d -s -g
  • C++ 设计模式:适配器模式(Adapter Pattern)
  • 在Unity中用Ab包加载资源(简单好抄)
  • 家政预约小程序05活动管理
  • Centos文件已删除空间未释放
  • leetcode 3280. 将日期转换为二进制表示 简单
  • Spring Boot 3 文件下载、多文件下载以及大文件分片下载、文件流处理、批量操作 和 分片技术
  • Java工程师实现视频文件上传minio文件系统存储及网页实现分批加载视频播放
  • 12.30-1-5学习周报
  • 【时时三省】(C语言基础)动态内存函数realloc
  • Node.js 常用命令全攻略
  • VSCode 插件开发实战(十三):如何添加个性化欢迎信息
  • Whiteboard-of-Thought——让大语言模型在白板上写下它们的推理过程,可以大大提高模型在视觉推理能力
  • Github - 如何提交一个带有“verified”标识的commit
  • 【漫话机器学习系列】031.数据增强(Dateset augmentation)
  • 安装、快速入门
  • npm 切换镜像源
  • MySQL5.7主从同步配置
  • mysql查询报错java.sql.SQLException: Illegal mix of collations for operation ‘UNION‘
  • 【智行安全】基于Synaptics SL1680的AI疲劳驾驶检测方案