zoukankan      html  css  js  c++  java
  • Django--中间件

    Django中间件

    用户访问的频率限制

    设置黑名单,白名单

    所有用户登陆校验

    只要是涉及到网址全局的功能 都要考虑使用中间件

    简介

    是一个处理django请求和相应的框架级别的钩子.是一个轻量,低级别的插件系统,用在全局范围内改变Django的输入和输出.每个中间件组件都负责做一个特定的功能.

    因为影响全局,使用不当会影响性能.

    django生命周期中中间件

    首先 它是放在在django项目里的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',
    ]
    

    那么中间件的方法什么时候被执行呢,如下图所示

    可以看到django默认有七个中间件,这七个中间件相当于django的保安,请求来的时候响应的时候都要走这里经过每一个中间件的检验,web网关接口走完的时候直接走到中间件,中间件检验完了去缓存数据库找有没有 没有的话再往后面走,回来的时候从views走到中间件然后到缓存数据库备份一份,最后在走浏览器.

    自定义中间件

    中间件可以定义五个方法.主要的是process_request和process_response

    这五个方法都是在特定的条件才会自动触发,按照生命周期顺序走的.

    操作步骤

    1. 新建一个文件夹,并建立子文件,任意名称即可(最好有辨识度)

      写类,固定继承

      from django.utils.deprecation import MiddlewareMixin
      class MyMiddle(MiddlewareMixin):
          ...
      
    2. 去配置把新建文件路径添加到中间件配置中

    自定义中间件解释

    重要

    1. process_request():

      请求来的时候经过...request,一旦里面返回了HttpResponse对象那么就不再往后执行了 会执行同一级别的process_response

      def process_request(self,request):
          print('process_rquest')
          return HttpResponse('我是第一个自定义中间件中HttpResponse对象返回值') # 原地直接返回
      
      
      
      
    2. process_response():

      响应走的时候 从下往上一次进入每一个中间件里面的process_response

      def process_response(self,request,response):
          print('我是第一个中间件里的process_response')
          return response
      

    明白了解

    process_view:路由匹配成功之后执行视图函数之前触发
                process_exception:当视图函数出现异常(bug)的时候自动触发
                process_template_response:当视图函数执行完毕之后并且返回的对象中含有render方法的情况下才会触发
    

    跨站请求伪造(csrf) ,设置scrf值,CBV加装饰器

    csrf---全称为cross-site request forgery

    什么是钓鱼网站?

    即假冒真正的网站欺骗用户,拿着真正的用户输入的数据,修改之后向真正的网址发送post请求

    举个例子

    """
    
    钓鱼网站就是说别人搭建了一个跟银行一模一样的web页面,你在网站转账的时候 ,钱确实会少,但是你转账的目标实际上是别人的账号,别人给你暴露的只是一
    个没有name属性的input的框.
    原理
    你输入的用户名  密码  支付密码 都会真实的提交给银行后台,但是转账的账,别人提前写好了一个隐藏带有name和value的input框.
    
    
    """
    

    这样是不是感觉特别可怕了,但是只要思想不滑坡,方法总比问题多

    解决钓鱼网站方法!

    只要是用户想要提交post请求的页面,那么在返回的时候提前设置好一个随机字符串,当用户提交post请求的时候 我就自动查找是不是有这个随机字符串,
    有则提交
    无则403
    

    'django.middleware.csrf.CsrfViewMiddleware'

    Django中这个中间件就是来检验用户提交post请求的时候有没有这个提交设置好的随机字符串.

    只要在form表单里加上{%csrf_token%}就可以通过校验了.

    <form action="" method="post">
        {% csrf_token %}
        <p>username:<input type="text" name="username"></p>
        <p>target_user:<input type="text" name="target_user"></p>
        <p>money:<input type="text" name="money"></p>
        <input type="submit">
    </form>
    
    1. ajax做法

    自己在页面上写上{%csrf_token%}获取到随机字符串,然后利用标签查找,在ajax发送的数据的data中加键值对

    data:{'username':'jason','csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()},

    1. django提供的模板语法,但是在前后端分离的时候就不能用了,所以不推荐。

      data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'}

    2. 方式三 拷贝官方js文件,最好把这段代码保存在本地,用的时候只需要写一个静态文件,配置一下即可

      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;
      }
      var csrftoken = getCookie('csrftoken');
      
      
      
      function csrfSafeMethod(method) {
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
      }
      
      $.ajaxSetup({
        beforeSend: function (xhr, settings) {
          if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
          }
        }
      });
      
      

      前端导入

      <script src="/static/setup.js"></script>

      如果说个别函数不想被校验怎么办?

      先导入一个模块

      from django.views.decorators.csrf import csrf_exempt,csrf_protect
      

      根据英文解释exempt就是免除校验的意思,protect就是保护的意思,就是让你校验,decorators即为装饰器

      根据以上推论得出(先写FBV型)

      @csrf_exempt #装饰了这个装饰器之后,就可以绕过校验了。不用那个随机字符串了
      def exem(request):
          return HttpResponse('exempt')
      
      @csrf_protect #装饰了这个装饰器就会被校验了。
      def pro(request):
          return HttpResponse('pro')
      

      写完FBV型,那么CBV型该怎么写呢

      		from django.views import View
              from django.views.decorators.csrf import csrf_exempt, csrf_protect
              from django.utils.decorators import method_decorator
              # 第一种
              # @method_decorator(csrf_exempt,name='dispatch')
              class MyCsrf(View):
                  # 第二种
                  @method_decorator(csrf_exempt)
                  def dispatch(self, request, *args, **kwargs):
                      return super().dispatch(request,*args,**kwargs)
                  def get(self,request):
                      return HttpResponse('hahaha')
                      
              除了csrf_exempt之外 所有的其他装饰器 在CBV上面都有三种方式
              @method_decorator(csrf_protect,name='post') #第一种
              class MyCsrf(View):
                  @method_decorator(csrf_protect)#第二种
                  def dispatch(self, request, *args, **kwargs):
                      return super().dispatch(request,*args,**kwargs)
                  def get(self,request):
                      return HttpResponse('hahaha')
      
                  @method_decorator(csrf_protect)#第三种
                  def post(self,request):
                      return HttpResponse('post')
      
  • 相关阅读:
    缓慢变化纬的解决方法
    行转列且有序
    异常处理
    继承
    js的隐式转化
    初步了解微任务
    axios中断请求AbortController
    Vue解决V-HTML指令潜在的XSS攻击('v-html' directive can lead to XSS attack vue/no-v-html)
    axios下载后台传过来的流文件并设置下载文件名(如excel)
    axios异步获取文件流数据
  • 原文地址:https://www.cnblogs.com/jhpy/p/11769166.html
Copyright © 2011-2022 走看看