zoukankan      html  css  js  c++  java
  • csrf原理

    简介:

    django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。

    全局:

    中间件 django.middleware.csrf.CsrfViewMiddleware

    局部:

    @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。

    @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

    注意:from django.views.decorators.csrf import csrf_exempt,csrf_protect

    原理:

    当用post提交数据的时候,django会去检查是否有一个csrf的随机字符串,如果没有就会报错,这也是之前我们一直将其注释的原因,错误如下:

    在django内部支持生成这个随机字符串

    通过scrf提交

    总结原理:当用户访问login页面的时候,会生成一个csrf的随机字符串,,并且cookie中也存放了这个随机字符串,当用户再次提交数据的时候会带着这个随机字符串提交,如果没有这个随机字符串则无法提交成功

    cookie中存放的csrftoken如下图

    用过ajax提交

    因为cookie中同样存在csrftoken,所以可以在js中通过:

    $.cooke("cstftoken")获取

    如果通过ajax进行提交数据,这里提交的csrftoken是通过请求头中存放,需要提交一个字典类型的数据,即这个时候需要一个key。

    在views中的login函数中:from django.conf import settings,然后打印print(settings.CSRF_HEADER_NAME)

    这里需要注意一个问题,这里导入的settings并不是我们在项目文件下看到的settings.py文件,这里是是一个全局的settings配置,而当我们在项目目录下的settings.py中配置的时候,我们添加的配置则会覆盖全局settings中的配置

    print(settings.CSRF_HEADER_NAME)打印的内容为:HTTP_X_CSRFTOKEN

    这里的HTTP_X_CSRFTOKEN是django在X_CSRF的前面添加了HTTP_,所以实际传递的是就是X_CSRFtoken,而在前端页面的ajax传递的时候由于不能使用下划线所以传递的是X_CSRFtoken

    下面是在前端ajax中写的具体内容:

    $("#btn1").click(function () {
            $.ajax({
                url:"/login/",
                type:"POST",
                data:{"usr":"root","pwd":"123"},
                headers:{ "X-CSRFtoken":$.cookie("csrftoken")},
                success:function (arg) {
    
                }
            })
        })
    

      但是如果页面中有多个ajax请求的话就在每个ajax中添加headers信息,所以可以通过下面方式在所有的ajax中都添加

           $.ajaxSetup({
                beforeSend:function (xhr,settings) {
                    xhr.setRequestHeader("X-CSRFtoken",$.cookie("csrftoken"))
                }
            });
    

      

    这样就会在提交ajax之前执行这个方法,从而在所有的ajax里都加上这个csrftoken

    这里的xhr是XMLHttpRequest的简写,ajax调用的就是这个方法

    如果想要实现在当get方式的时候不需要提交csrftoken,当post的时候需要,实现这种效果的代码如下:

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

      这样就实现了当GET|HEAD|OPTIONS|TRACE这些方式请求的时候不需要提交csrftoken

    总结:

    1、    csrf在ajax提交的时候通过请求头传递的给后台的

    2、    csrf在前端的key为:X-CSRFtoken,到后端的时候django会自动添加HTTP_,并且最后为HTTP_X_CSRFtoken

    3、    csrf在form中提交的时需要在前端form中添加{%csrftoken%}

  • 相关阅读:
    vue form dynamic validator All In one
    TypeScript api response interface All In One
    closable VS closeable All In One
    macOS 如何开启 WiFi 热点 All In One
    vue css inline style All In One
    vs2010里面 新建网站里面的 asp.net网站 和 新建项目里面的 asp.net Web应用程序 的区别 (下)
    牛腩新闻 59 整合添加新闻页 FreeTextBox 富文本编辑器,检测到有潜在危险的 Request.Form 值,DropDownList 的使用
    牛腩新闻 61尾声: error.aspx的使用 防止报错
    vs2010里面 新建网站里面的 asp.net网站 和 新建项目里面的 asp.net Web应用程序 的区别 (上)
    牛腩新闻 62:尾声续2 asp.net的编译和发布
  • 原文地址:https://www.cnblogs.com/manjian/p/11812063.html
Copyright © 2011-2022 走看看