Django进阶之CSRF的解决


Posted in Python onAugust 01, 2018

简介

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进阶之CSRF的解决

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

通过form提交

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

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

Django进阶之CSRF的解决

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

cookie中存放的csrftoken如下图

Django进阶之CSRF的解决

通过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%}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
简单介绍Python中的filter和lambda函数的使用
Apr 07 Python
Python的Flask框架中集成CKeditor富文本编辑器的教程
Jun 13 Python
详解supervisor使用教程
Nov 21 Python
centos 安装python3.6环境并配置虚拟环境的详细教程
Feb 22 Python
Python简单读写Xls格式文档的方法示例
Aug 17 Python
pycharm运行程序时在Python console窗口中运行的方法
Dec 03 Python
Python使用folium excel绘制point
Jan 03 Python
Pandas读取并修改excel的示例代码
Feb 17 Python
Django密码存储策略分析
Jan 09 Python
Python+redis通过限流保护高并发系统
Apr 15 Python
解决selenium+Headless Chrome实现不弹出浏览器自动化登录的问题
Jan 09 Python
python 制作磁力搜索工具
Mar 04 Python
python3利用venv配置虚拟环境及过程中的小问题小结
Aug 01 #Python
mvc框架打造笔记之wsgi协议的优缺点以及接口实现
Aug 01 #Python
python爬虫自动创建文件夹的功能
Aug 01 #Python
浅谈关于Python3中venv虚拟环境
Aug 01 #Python
python Web开发你要理解的WSGI & uwsgi详解
Aug 01 #Python
Django教程笔记之中间件middleware详解
Aug 01 #Python
flask框架中勾子函数的使用详解
Aug 01 #Python
You might like
一些php项目中比较通用的php自建函数的详解
2013/06/06 PHP
浅谈PHP变量作用域以及地址引用问题
2013/12/27 PHP
php判断字符串在另一个字符串位置的方法
2014/02/27 PHP
PHP简单选择排序算法实例
2015/01/26 PHP
php返回当前日期或者指定日期是周几
2015/05/21 PHP
基于laravel belongsTo使用详解
2019/10/18 PHP
动态为事件添加js代码示例
2009/02/15 Javascript
jQuery 行级解析读取XML文件(附源码)
2009/10/12 Javascript
js实现获取两个日期之间所有日期的方法
2016/06/17 Javascript
JavaScript中匿名函数的递归调用
2017/01/22 Javascript
jQuery实现对网页节点的增删改查功能示例
2017/09/18 jQuery
Vue.js中使用iView日期选择器并设置开始时间结束时间校验功能
2018/08/12 Javascript
详谈js的变量提升以及使用方法
2018/10/06 Javascript
js实现自定义滚动条的示例
2020/10/27 Javascript
[03:58]2014DOTA2国际邀请赛 龙宝赛后解密DK获胜之道
2014/07/14 DOTA
[53:38]OG vs LGD 2018国际邀请赛淘汰赛BO3 第三场 8.26
2018/08/30 DOTA
Python求算数平方根和约数的方法汇总
2016/03/09 Python
分享python数据统计的一些小技巧
2016/07/21 Python
django轻松使用富文本编辑器CKEditor的方法
2017/03/30 Python
Python logging管理不同级别log打印和存储实例
2018/01/19 Python
python3实现从kafka获取数据,并解析为json格式,写入到mysql中
2019/12/23 Python
python数字类型math库原理解析
2020/03/02 Python
python 比较字典value的最大值的几种方法
2020/04/17 Python
Python 在 VSCode 中使用 IPython Kernel 的方法详解
2020/09/05 Python
python 基于DDT实现数据驱动测试
2021/02/18 Python
纽约复古灵感的现代珠宝品牌:Lulu Frost
2018/03/03 全球购物
澳大利亚玩具剧场:Toy Playhouse
2019/03/03 全球购物
工作散漫检讨书
2014/09/16 职场文书
校长四风对照检查材料
2014/09/27 职场文书
小学生表扬稿范文
2015/05/05 职场文书
2015小学教师德育工作总结
2015/05/12 职场文书
公司酒会主持词
2015/07/02 职场文书
初中数学教学反思范文
2016/02/17 职场文书
2019学生会干事辞职信
2019/06/27 职场文书
浅谈resultMap的用法及关联结果集映射
2021/06/30 Java/Android
Windows server 2022创建创建林、域树、子域的步骤
2022/06/25 Servers