• 跨站请求伪造(csrf)中间件整理


    一. CSRF中间件  

      字面意思跨站请求伪造; 即模仿个请求朝服务器发送,django中对跨站伪造的请求有相应的校验

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

        csrf_exempt  给单个视图排除校验,以装饰器形式给某个视图加上,则该视图就不会进行校验

                    局部禁用的前提是全局有校验

        csrf_protect  给单个视图必须校验,以装饰器形式给某个视图加上,则该视图就必须进行校验

                    即使注释调settings中的46行也必须得校验.  局部使用的前提是全局没有校验

    二. csrt源码解析其校验的本质大概流程是:

      1. 在process_request内,从请求的cookie中获取csrftoken的值,保存为scrf_token

      2. 在process_view内:

         > 如果视图函数加上了csrf_exempt的装饰器  不做校验

         > 如果请求方式是'GET', 'HEAD', 'OPTIONS', 'TRACE' 也不做校验

         > 其它的请求方式就要进行校验了,校验的实质如下:

           1.从request.POST中获取csrfmiddlewaretoken对象的值

           2.从请求头中获取csrfmiddlewaretoken对象的值

           3.用获取到的csrfmiddlewaretoken的值和csrftoken的值做比较,如果校验成功,流程继续;校验不成功

              则拒绝;  1和2中只要有1个能获取到csrfmiddlewaretoken的值即可,不用两个中都有.

    总结: 两点要求,1.浏览器必须带有cookie;  2. post请求体中或请求头中要能获取到csrfmiddlewaretoken值

     

    三.针对以上总结的两点,做相应的处理,处理办法如下

         确保浏览器带有cookie的两种方式:

              > 在form表单内加入{% csrf_token %}

              > 不使用{% csrf_token %},导入from django.views.decorators.csrf import ensure_csrf_cookie

                 将ensure_csrf_cookie以装饰器形式加在视图上,保证返回的相应有cookie

          确保能从post请求体中或请求头信息中获取到csrfmiddlewaretokende的方式:

            > 页面中加入{% csrf_token %}标签

             1.获取标签值,加入post请求体中,  csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val()

             2.获取标签值,加入post请求头中,  headers: {"X-CSRFToken": $('[name="csrfmiddlewaretoken"]').val()}

            > 上面1或2都是给单个的ajax请求加csrfmiddlewaretokende,这里再介绍个通过引入js文件形式

              给全局所有ajax头部加入csrfmiddlewaretokende的办法,代码思路如下: (万能办法)

             1.通过django官网提供的代码来实现,首先项目下static文件夹内新建js文件,复制以下代码:

             2.以script标签在html页面导入新建的这个a.js文件, <script src=’/static/a.js’></script>

               它的作用是给每个请求头信息上加crsfmiddlewaretoken信息

         猜测: 引入js文件形式可同时让浏览器带cookie和让请求头带crsfmiddlewaretoken信息,因为使用

               CBV写ajax文件上传时,html中没加{%csrf_token%},views中也没用ensure_csrf_token装饰器

    四. 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);
    
        }
    
      }
    
    });
    

      

  • 相关阅读:
    计算与软件工程 作业一
    C语言程序设计数组实验实验报告
    C语言程序设计第五次实验报告
    C语言程序设计第四次实验报告
    C语言程序设计第三次实验报告
    C程序设计实验报告第二次实验
    关于证书如何完成身份验证(SSL证书)
    openflow流表项中有关ip掩码的匹配的问题(控制器为ryu)
    解决sublime安装插件被墙失败的方法
    区块链技术与应用(二)之比特币中的数据结构
  • 原文地址:https://www.cnblogs.com/ellisonzhang/p/10702483.html
Copyright © 2020-2023  润新知