csrf原理

简介:前端

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

全局:ajax

中间件 django.middleware.csrf.CsrfViewMiddlewaredjango

局部:后端

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

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

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

原理:

当用post提交数据的时候,django会去检查是否有一个csrf的随机字符串,若是没有就会报错,这也是以前咱们一直将其注释的缘由,错误以下:ui

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

经过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

总结:

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

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

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

相关文章
相关标签/搜索