Django中间件Middleware,中间件的两种定义方式,类定义和函数定义,系统默认中间件的介绍,中间件的执行顺序

Django中间件

1. 中间件是什么?

简单来讲,中间件类似于一个插件,在我们通过路由绑定函数进行视图方法实现之前,通过插入多个插件,在实现之前提前修改请求体或者提前返回结果

例如我们的业务需求:

需要实现访问网站的请求中,只要没有登录账号的就全部给他跳转到/login页面

按照以前的实现,我们需要在每个视图里面都加入一个session判断,没有的就返回重定向

但是有了中间件,我们就可以在请求达到视图函数之前,对所有的请求进行提前判断

2. 中间件的代码形式

2.1 函数格式编写

这里为什么要用闭包函数,是因为必须要实现一个类似于类的__ init __方法,所以才需要使用闭包

def simple_middleware(get_response):
    # 要这样写,是因为中间件在程序启动的时候要进行初始化,所以初始化的时候,就会执行simple_middleware(get_response)
    def middleware(request):
        # 这里写需要实现的功能
        
        response = get_response(request)
        
        # 最后需要返回一个Response对象,如果希望不改变原本的返回就直接返回 get_response(request)
        return response
    return middleware

2.2 类格式编写

class SimpleMiddleware:
    def __init__(self, get_response):
        """
        	这里用作初始化对象,设置了get_response属性	
        """
        self.get_response = get_response

    def __call__(self, request):
        # 这里写需要实现的功能,也就是执行视图函数或者[下一个中间件之前]要实现的功能

        response = self.get_response(request)

        # 返回Response对象,如果希望不改变原本的返回就直接返回 self.get_response(request)

        return response

3. 中间件的注册

中间件需要在Django项目的setttings.py中进行注册

settings.py

# 这是默认的中间件
MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    'Django05.middleware.simple_middleware', # 注册我们的中间件,类了话传类名,方法传方法名
]

4. 系统默认中间件

  1. django.middleware.security.SecurityMiddleware

    负责处理安全相关的头部和操作,比如添加X-XSS-Protection头部和严格传输安全头部(STS)。

  2. django.contrib.sessions.middleware.SessionMiddleware

    处理会话相关的功能,包括初始化会话对象、处理会话数据的存储和访问,以及管理会话的生命周期。

  3. django.middleware.common.CommonMiddleware:

    提供一些通用的处理,比如设置响应头部、处理请求路径尾部的斜杠、处理URL重定向等。

  4. django.middleware.csrf.CsrfViewMiddleware:

    处理 CSRF(跨站请求伪造)保护。它会验证请求中的 CSRF token,并防止来自不受信任站点的 POST、PUT、DELETE 请求。

  5. django.contrib.auth.middleware.AuthenticationMiddleware:

    处理用户认证相关的功能。它会在每个请求中对用户进行认证,并将认证后的用户对象添加到 request.user 中。

  6. django.contrib.messages.middleware.MessageMiddleware:

    处理用户消息(如闪现消息)的功能。它在请求处理过程中,将消息存储在会话中,并在下一次请求时提取出来以便在模板中显示。

  7. django.middleware.clickjacking.XFrameOptionsMiddleware:

    处理点击劫持保护。它通过添加 X-Frame-Options 头部来阻止网页被嵌入到 frame 或 iframe 中,提高网站的安全性。

5. 中间件的执行顺序

简单来讲:

收到请求:顺序执行

返回请求:逆序执行

我们在settings.py中的中间件,会按照列表传入的顺序进行依次执行

下方的图,是中间件请求顺序的简单图解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bONbKg7g-1690628601824)(C:\Users\RYF55\AppData\Roaming\Typora\typora-user-images\image-20230729171053118.png)]

案例:

# 现在有两个中间件
# 1. 需要先进行用户是否登录的验证
# 2. 需要进行用户是否为管理员的验证

# 如果1验证不通过,就让用户去登录
# 如果2验证不通过,就返回状态码403

此时,我们请求的验证顺序是 1-2,所以注册中间件应该这样注册
MIDDLEWARE = [
	验证登录中间件,
	验证管理员中间件,
]

所以:
	验证登录中间件 ->通过-> 验证管理员中间件 不通过 <-(最先返回不通过)
最终顺序就是:
	收到请求,顺序执行|返回请求,逆序执行

6. 案例实践,定义一个中间件

需求分析:

  1. 如果用户请求的session中没有userid,那么视为用户没有登录
  2. 如果是GET请求没有登录,直接302重定向到 login 页面
  3. 如果是POST请求没有登录,则返回一个字符串,你没有登录
  4. 如果登录了,就正常执行请求
  5. 并且支持设置部分页面需要验证,例如login页面不需要验证登录,userinfo页面需要验证登录

6.1 定义中间件

6.1.1 函数方式定义中间件

"""
    自定义Django请求中间件
"""
from django.shortcuts import redirect
from django.http import JsonResponse


def is_login_auth(get_response):
    """
        定义验证用户是否登录中间件
    :param get_response: 请求需要返回的Response对象(Django中间件通用定义方式)
    """

    def middleware(request):
        need_auth_path = [
            '/userinfo/'  # 需要进行验证登录有效性的路由
        ]
        if request.path not in need_auth_path:
            return get_response(request)  # 如果路由不在验证列表中,则直接返回原请求对象
        method = request.method  # 获取请求方法
        userid = request.session.get("userid")  # 从session中读取userid
        if userid:  # 如果能读取到userid证明登录有效
            return get_response(request)  # 直接返回原请求对象
        # 如果读取不到,则证明登录失效
        if method == 'GET':  # 如果是GET请求,就重定向到登陆页面
            return redirect('login')
        else:  # 如果是POST请求,就返回JSON
            return JsonResponse({"status": -1, "message": '登录失效!!!', "data": None})

    return middleware

6.1.2 类定义中间件

from django.shortcuts import redirect
from django.http import JsonResponse

class LoginAuth:
    """
        定义验证用户是否登录中间件
    :param get_response: 请求需要返回的Response对象(Django中间件通用定义方式)
    """

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        """
            回调函数,返回Response对象
        """
        need_auth_path = [
            '/userinfo/'  # 需要进行验证登录有效性的路由
        ]
        if request.path not in need_auth_path:
            return self.get_response(request)  # 如果路由不在验证列表中,则直接返回原请求对象
        method = request.method  # 获取请求方法
        userid = request.session.get("userid")  # 从session中读取userid
        if userid:  # 如果能读取到userid证明登录有效
            return self.get_response(request)  # 直接返回原请求对象
        # 如果读取不到,则证明登录失效
        if method == 'GET':  # 如果是GET请求,就重定向到登陆页面
            return redirect('login')
        else:  # 如果是POST请求,就返回JSON
            return JsonResponse({"status": -1, "message": '登录失效!!!', "data": None})

6.2 注册中间件

settings.py

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    # "django.middleware.csrf.CsrfViewMiddleware", # 取消csrf验证
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    'Django05.middleware.LoginAuth', # 使用类注册中间件
]

6.3 查看请求效果

下图是有session的情况,直接返回用户信息

在这里插入图片描述

没有session的情况,返回302重定向

在这里插入图片描述

ameOptionsMiddleware",
‘Django05.middleware.LoginAuth’, # 使用类注册中间件
]




## 6.3 查看请求效果

## **下图是有session的情况,直接返回用户信息**

![在这里插入图片描述](https://img-blog.csdnimg.cn/82987be0039648d8b0e4f99e8bb60149.png#pic_center)


## 没有session的情况,返回302重定向

![在这里插入图片描述](https://img-blog.csdnimg.cn/638564187be94f9db2ca4707701f33ea.png#pic_center)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值