简介

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内部支持生成这个随机字符串

通过form提交

在form表单里面需要添加{%csrf_token%}

这样当你查看页面源码的时候,可以看到form中有一个input是隐藏的

总结原理:当用户访问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调用的就是这个方法

而这里settings指的是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

重点补充部分:

情况一:如果是大部分网页登录都需要csrftoken验证,可以通过中间件的形式,而剩余的小部分则可以通过添加装饰器,取消中间件的功能,如下:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt

所需要装饰的函数

情况二:如情况一相反:

from django.views.decorators.csrf import csrf_protect

@csrf_protect

所需要装饰的函数

总结

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

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

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

4、    csrf局部控制,通过装饰器进行控制

最新文章

  1. Xamarin.ios 调用接口
  2. MySQL修改root账号密码
  3. PHP基础知识之函数
  4. Mac安装GitLab CE记录
  5. Jquery day02
  6. php单例模式的研究
  7. Navicat(连接) -1高级设置
  8. python的文件操作方法
  9. Android应用开发学习笔记之菜单
  10. eclipse 最全快捷键(网络收集)
  11. React组件二
  12. 【CSS】盒子模型 之 IE 与W3C的盒子模型对比
  13. Hardcoded string XXX,&…
  14. Q:同时安装了python2和python3的电脑下pip的使用
  15. JavaScript之图片懒加载的实现
  16. Codechef March Challenge 2014——The Street
  17. oppo8.0系统怎么无需Root激活Xposed框架的经验
  18. 4.hadoop的安装与配置
  19. vue的分页组件
  20. Leetcode 150

热门文章

  1. mac java_home等系统参数配置
  2. phpcms 标签含义大全
  3. HTTP常用头部信息
  4. python 面向对象(一)初识面向对象
  5. getResource()和getResourceAsStream以及路径问题【转】【补】
  6. 学习总结:CSS(二)块级与行级元素特性、盒模型、层模型、BUG与BFC、浮动模型
  7. 【leetcode-88,21】 合并两个有序数组/链表
  8. HDU 1097(m次幂的个位数 规律)
  9. Part-Eight 模板与群体数据的组织
  10. python学习路线--从入门到入土