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中使用M2Crypto模块实现AES加密的教程
Apr 08 Python
Python函数中的函数(闭包)用法实例
Mar 15 Python
解决Python出现_warn_unsafe_extraction问题的方法
Mar 24 Python
Python实现视频下载功能
Mar 14 Python
Django自定义分页与bootstrap分页结合
Feb 22 Python
Appium Python自动化测试之环境搭建的步骤
Jan 23 Python
简单了解Python matplotlib线的属性
Jun 29 Python
关于Python核心框架tornado的异步协程的2种方法详解
Aug 28 Python
Python调用graphviz绘制结构化图形网络示例
Nov 22 Python
windows上彻底删除jupyter notebook的实现
Apr 13 Python
python 如何实现遗传算法
Sep 22 Python
python爬虫selenium模块详解
Mar 30 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安全编程之加密功能
2006/10/09 PHP
php删除字符串末尾子字符,删除开始字符,删除两端字符(实现代码)
2013/06/27 PHP
php实现与erlang的二进制通讯实例解析
2014/07/23 PHP
PHP使用get_headers函数判断远程文件是否存在的方法
2014/11/28 PHP
PHP实现简易计算器功能
2020/08/28 PHP
Thinkphp5框架ajax接口实现方法分析
2019/08/28 PHP
laravel 框架结合关联查询 when()用法分析
2019/11/22 PHP
发布一个基于javascript的动画类 Fx.js
2010/11/05 Javascript
js中opener与parent的区别详细解析
2014/01/14 Javascript
JS判断iframe是否加载完成的方法
2016/08/03 Javascript
微信小程序页面开发注意事项整理
2017/05/18 Javascript
es6 字符串String的扩展(实例讲解)
2017/08/03 Javascript
VUE中的无限循环代码解析
2017/09/22 Javascript
Angular4编程之表单响应功能示例
2017/12/13 Javascript
nodejs超出最大的调用栈错误问题
2017/12/27 NodeJs
jQuery AJAX 方法success()后台传来的4种数据详解
2018/08/08 jQuery
小程序新版订阅消息模板消息
2019/12/31 Javascript
[01:03:41]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第三场 2月2日
2021/03/11 DOTA
python搜索指定目录的方法
2015/04/29 Python
Java中重定向输出流实现用文件记录程序日志
2015/06/12 Python
Windows下Eclipse+PyDev配置Python+PyQt4开发环境
2016/05/17 Python
Django 实现购物车功能的示例代码
2018/10/08 Python
Python数据类型之Set集合实例详解
2019/05/07 Python
Django如何实现上传图片功能
2019/08/16 Python
python如何调用字典的key
2020/05/25 Python
加拿大最大的钻石商店:Peoples Jewellers
2018/01/01 全球购物
英国户外玩具儿童游乐设备网站:TP Toys(蹦床、攀爬框架、秋千、滑梯和游戏屋)
2018/04/09 全球购物
如何用Python输出一个Fibonacci数列
2016/08/28 面试题
安全标准化汇报材料
2014/02/03 职场文书
2014年元旦活动方案
2014/02/15 职场文书
留学顾问岗位职责
2014/04/14 职场文书
新颖的化妆品活动方案
2014/08/21 职场文书
校长师德师风自我剖析材料
2014/09/29 职场文书
2014年后勤工作总结范文
2014/12/16 职场文书
个人廉洁自律总结
2015/03/06 职场文书
Java代码规范与质量检测插件SonarLint的使用
2022/08/05 Java/Android