Django中间件MiddleWare

Posted timetellu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django中间件MiddleWare相关的知识,希望对你有一定的参考价值。

一、什么是中间件

  中间件是一个用来处理Django的请求和响应的框架级别的钩子。

  中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。

我们一直都在使用中间件,只是没有注意到而已,打开Django项目的Settings.py文件,看到下图的MIDDLEWARE配置项。

  MIDDLEWARE配置项是一个列表,列表中是一个个字符串,这些字符串其实是一个个类,也就是一个个中间件。

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,
]

二、自定义中间件详情  

  中间件可以定义五个方法,分别是:(主要的是process_request和process_response)

  • process_request(self,request)
    • 中间件的process_request方法是在执行视图函数之前 执行的。
    • 当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,从前到后依次执行的。
    • 不同中间件之间传递的request都是同一个对象
  • process_view(self, request, view_func, view_args, view_kwargs)
  • process_template_response(self,request,response)
  • process_exception(self, request, exception)
  • process_response(self, request, response)
    • 多个中间件中的process_response方法是按照MIDDLEWARE中的注册顺序倒序执行的,也就是说第一个中间件的process_request方法首先执行,而它的process_response方法最后执行,最后一个中间件的process_request方法最后一个执行,它的process_response方法是最先执行。
    • response是视图函数返回的HttpResponse对象。该方法的返回值也必须是HttpResponse对象。

  以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。

三、中间件版登录验证 

  中间件版的登录验证需要依靠session,所以数据库中要有django_session表。

  urls.py

技术图片
from django.conf.urls import url
from django.contrib import admin
from app01 import views


urlpatterns = [
    url(r^admin/, admin.site.urls),
    url(r^login/, views.login,name="login"),
]
urls.py

  views.py

技术图片
from django.shortcuts import render, HttpResponse, redirect
from django.views.decorators.csrf import csrf_exempt

def index(request):
    return HttpResponse(this is index)


def home(request):
    return HttpResponse(this is home)

@csrf_exempt
def login(request):
    if request.method == "POST":
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")

        if user == "alex" and pwd == "123456":
            # 设置session
            request.session["user"] = user
            # 获取跳到登陆页面之前的URL
            next_url = request.GET.get("next")
            # 如果有,就跳转回登陆之前的URL
            if next_url:
                return redirect(next_url)
            # 否则默认跳转到index页面
            else:
                return redirect("/index/")
    return render(request, "login.html")
views.py

  login.html

技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>登录页面</title>
</head>
<body>
{% csrf_token %}
<form action="{% url ‘login‘ %}" method="post">
    <p>
        <label for="user">用户名:</label>
        <input type="text" name="user" id="user">
    </p>
    <p>
        <label for="pwd">密 码:</label>
        <input type="text" name="pwd" id="pwd">
    </p>
    <input type="submit" value="登录">
</form>
</body>
</html>
login.html

 

  my_middleware.py

技术图片
‘‘‘
自定义的中间件
‘‘‘
from django.utils.deprecation import MiddlewareMixin


class AuthMD(MiddlewareMixin):
    white_list = [/login/]      #白名单
    black_list = [/black/]      #黑名单

    def process_request(self,request):
        from django.shortcuts import redirect,HttpResponse

        next_url = request.path_info
        print(next_url,request.get_full_path())

        if next_url in self.white_list or request.session.get("user"):
            return
        elif next_url in self.black_list:
            return HttpResponse("不合法的URL")
        else:
            return redirect("/login/?next={}".format(next_url))
my_middleware.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,
    my_middleware.AuthMD,         # 自定义中间件AuthMD进行注册     
] 
settings.py

  AuthMD中间件注册后,所有的请求都要走AuthMD的process_request方法。

  访问的URL在白名单内或者session中有user用户名,则不做阻拦走正常流程;

  如果URL在黑名单中,则返回This is an illegal URL的字符串;

  正常的URL但是需要登录后访问,让浏览器跳转到登录页面。

注:AuthMD中间件中需要session,所以AuthMD注册的位置要在session中间的下方。

附:Django请求流程图

技术图片

 

以上是关于Django中间件MiddleWare的主要内容,如果未能解决你的问题,请参考以下文章

Django 中间件 Middleware

django之(中间件)middleware

django之中间件middleware

利用django中间件django.middleware.csrf.CsrfViewMiddleware防止csrf攻击

中间件-Middleware

Django 中间件