Django进阶之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内部支持生成这个随机字符串
通过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调用的就是这个方法
如果想要实现在当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%}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 厦门一手机店被5少年洗劫!官方:已做完笔录、正在调查
下一篇: 你是在修炼什么
推荐阅读
-
android UI进阶之android中隐藏的layout 抽屉的使用方法
-
Bootstrap modal 多弹窗之叠加关闭阴影遮罩问题的解决方法
-
PHP之浮点数计算比较以及取整数不准确的解决办法
-
csrf攻击防范的方法(csrf攻击原理与解决技巧)
-
如何搜索查找并解决Django相关的问题
-
Python的Django应用程序解决AJAX跨域访问问题的方法
-
vue填坑之webpack run build 静态资源找不到的解决方法
-
Django中如何防范CSRF跨站点请求伪造攻击的实现
-
django 商城项目之购物车以及python中的一些redis命令
-
Django1.3添加app提示模块不存在的解决方法