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设计足球联赛赛程表程序的思路与简单实现示例
Jun 28 Python
python 实现红包随机生成算法的简单实例
Jan 04 Python
Python程序退出方式小结
Dec 09 Python
python爬虫框架scrapy实现模拟登录操作示例
Aug 02 Python
利用Pyhton中的requests包进行网页访问测试的方法
Dec 26 Python
Python3.8中使用f-strings调试
May 22 Python
python查看文件大小和文件夹内容的方法
Jul 08 Python
对Django 中request.get和request.post的区别详解
Aug 12 Python
Python如何使用内置库matplotlib绘制折线图
Feb 24 Python
如何使用Cython对python代码进行加密
Jul 08 Python
在keras中对单一输入图像进行预测并返回预测结果操作
Jul 09 Python
python生成word合同的实例方法
Jan 12 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执行速度全攻略(上)
2006/10/09 PHP
PHP Squid中可缓存的动态网页设计
2008/09/17 PHP
php实现判断访问来路是否为搜索引擎机器人的方法
2015/04/15 PHP
dvwa+xampp搭建显示乱码的问题及解决方案
2015/08/23 PHP
PHP判断来访是搜索引擎蜘蛛还是普通用户的代码小结
2015/09/14 PHP
PHP实现查询手机归属地的方法详解
2017/04/28 PHP
JavaScript实现Sleep函数的代码
2007/03/04 Javascript
wap手机图片滑动切换特效无css3元素js脚本编写
2014/07/28 Javascript
js简单抽奖代码
2015/01/16 Javascript
jQuery实现的手机发送验证码倒计时效果代码分享
2015/08/24 Javascript
jQuery Validate初步体验(一)
2015/12/12 Javascript
7个去伪存真的JavaScript面试题
2016/01/07 Javascript
jQuery Easyui Datagrid实现单行的上移下移及保存移动的结果
2016/08/15 Javascript
AngularJS入门教程之更多模板详解
2016/08/19 Javascript
JS 滚动事件window.onscroll与position:fixed写兼容IE6的回到顶部组件
2016/10/10 Javascript
深入理解jquery中的each用法
2016/12/14 Javascript
jQuery实现贪吃蛇小游戏(附源码下载)
2017/03/04 Javascript
获取url中用&隔开的参数实例(分享)
2017/05/28 Javascript
JavaScript使用表单元素验证表单的示例代码
2019/08/20 Javascript
Python的Django框架中从url中捕捉文本的方法
2015/07/20 Python
Python随机生成带特殊字符的密码
2016/03/02 Python
Python模拟登录的多种方法(四种)
2018/06/01 Python
python使用wxpy轻松实现微信防撤回的方法
2019/02/21 Python
在django中图片上传的格式校验及大小方法
2019/07/28 Python
python getpass实现密文实例详解
2019/09/24 Python
Python AutoCAD 系统设置的实现方法
2020/04/01 Python
浅谈Python 函数式编程
2020/06/20 Python
python如何对链表操作
2020/10/10 Python
台湾租车首选品牌:IWS艾维士租车
2019/05/03 全球购物
红色故事汇观后感
2015/06/18 职场文书
Redis做数据持久化的解决方案及底层原理
2021/07/15 Redis
Springboot/Springcloud项目集成redis进行存取的过程解析
2021/12/04 Redis
python中出现invalid syntax报错的几种原因分析
2022/02/12 Python
Python简易开发之制作计算器
2022/04/28 Python
Spring Boot优化后启动速度快到飞起技巧示例
2022/07/23 Java/Android