Django的中间件

Django的中间件

什么是中间件

中间件是一个用来处理Django的请求和响应的框架级别的钩子。它 是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。

Django默认使用的中间件

在Django项目的setting.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',
]

中间件是按照配置文件中的顺序来执行地

自定义中间件

在项目的任意位置新建一个文件夹,文件夹中新建任意一个.py文件,在文件中添加如下内容:

from django.utils.deprecation import MiddlewareMixin

class MyMiddle(MiddlewareMixin):
    ...

上面就是一个没有任何方法的中间件,如果想要让Django运行你定义的中间件,那么就需要在你的setting.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',
    'middlewareMixin.log_auth.MyMiddle',    # : 就是这个
]

Django为用户提供了五个中间件的方法,常用的只有两个:

  • process_request(self, request)

    当请求来时,会触发这个方法,在将request传给视图函数之前可以对request进行一系列操作

    def process_request(self, request):
        print("请求来时会走这个")
    

    如果我们在这个方法里面返回了HttpResponse对象,那么便会触发当前对象中的process_response方法,并原路返回给浏览器

    def process_request(self, request):
        return HttpResponse("你的请求不符合我的要求,拒绝访问!")
    
  • process_response(self, request, response)

    上面我们讲到会触发同级的process_response方法,这个方法必须将response返回,并且必须是按照这个位置写,因为调用这个方法的传参方式是按照位置传参,第二个就是response对象

    def process_response(self, request, response):
        print("响应时会走这个")
        return response
    
  • process_view

    当我们的路由匹配成功之后,在视图函数执行之前

  • process_exception

    当视图函数出现异常时自动触发

  • process_template_response

    当视图函数执行完毕,返回的HttpResponse对象中包含render方法时才会触发

csrf:跨站请求伪造

跨站请求伪造就是相当于钓鱼网站。模仿一个正常的网站来盗取得你用户名密码之类的。

解决跨站请求伪造的策略

只要是用户想要提交post请求的页面 我在返回给用户的时候就提前设置好一个随机字符串

  • 当用户提交post请求的时候 我会自动先取查找是否有该随机字符串
  • 如果有 正常提交
  • 如果没有 直接报403

在Django中已经为我们写好了一个解决跨站请求伪造的中间件,我们只需要会使用就可以了

使用Django自带的csrf

提交方式
  • form表单提交

    我们只需要在form表单中添加 {% csrf_token %} 经过后端页面渲染就会变成一个隐藏的input框,框内的值就是服务器生成的随机字符串

  • ajax提交

    • 第一种:在页面上随便一个地方添加 {% csrf_token %} 通过获取值

    • 第二种:直接在ajax的data数据中添加一组键值对:'csrfmiddlewaretoken':'{{ csrf_token }}'

    • 第三种:通过js来获取csrf

      function getCookie(name) {
          var cookieValue = null;
          if (document.cookie && document.cookie !== '') {
              var cookies = document.cookie.split(';');
              for (var i = 0; i < cookies.length; i++) {
                  var cookie = jQuery.trim(cookies[i]);
                  // Does this cookie string begin with the name we want?
                  if (cookie.substring(0, name.length + 1) === (name + '=')) {
                      cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                      break;
                  }
              }
          }
          return cookieValue;
      }
      
      
      $.ajax({
          url: "",
          type: "post",
          headers: {"X-CSRFToken": getCookie('csrftoken')},
          success: function (res) {
              alert(res);
          }
      })
      

我们除了可以在前端页面上设置csrf之外还可以在后端设置本次请求不校验

  • FBV

    from django.views.decorators.csrf import csrf_exempt
    
    @csrf_exempt   # 只要加装了这个装饰糖那么就不会对这个接口进行csrf检测
    def test_csrf(request):
    
        if request.method == "POST":
            return HttpResponse("成功接收请求!")
    
        return render(request, "test.html")
    
  • CBV

    from django.views.decorators.csrf import csrf_exempt
    from django.utils.decorators import method_decorator
    # 第一种
    # @method_decorator(csrf_exempt,name='dispatch')   # 将装饰器加装在类上面指定dispatch方法
    class MyCsrf(View):
        # 第二种   # 将装饰器加装在dispatch方法上面
        @method_decorator(csrf_exempt)
        def dispatch(self, request, *args, **kwargs):
            return super().dispatch(request, *args, **kwargs)
        def get(self, request):
            return HttpResponse('hahaha')
        def post(self, request):
            return HttpResponse("成功接收请求!")
    
posted @ 2019-10-31 22:14  戈达尔  阅读(100)  评论(0编辑  收藏  举报