Django csrf 验证问题的实现


Posted in Python onOctober 09, 2018

关于 csrf 的基本了解

百度百科:CSRF(Cross-site request forgery)跨站请求伪造,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。通过伪装来自受信任用户的请求来利用受信任的网站。

简单来说就是攻击者盗用你的身份,以你的名义来发送恶意请求。比如说用户通过账号密码访问了网站A,A网站将一些cookie信息保存在浏览器中实现用户状态行为跟踪。这时用户又打开了B网站,B网站返回了一些恶意代码,并请求访问A。这样浏览器就会携带cookie以用户的权限访问A网站并执行代码。而在服务器看来,这些都是正常的用户操作。

Django 提供的 CSRF 防护机制

django 第一次响应来自某个客户端的请求时,会在服务器端随机生成一个 token,把这个 token 放在 cookie 里。然后每次 POST 请求都会带上这个 token,

这样就能避免被 CSRF 攻击。

1.在返回的 HTTP 响应的 cookie 里,django 会为你添加一个 csrftoken 字段,其值为一个自动生成的 token
2.在所有的 POST 表单时,必须包含一个 csrfmiddlewaretoken 字段 (只需要在模板里加一个 tag, django 就会自动帮你生成,见下面)
3.在处理 POST 请求之前,django 会验证这个请求的 cookie 里的 csrftoken 字段的值和提交的表单里的 csrfmiddlewaretoken 字段的值是否一样。如果一样,则表明这是一个合法的请求,否则,这个请求可能是来自于别人的 csrf 攻击,返回 403 Forbidden.
4.在所有 ajax POST 请求里,添加一个 X-CSRFTOKEN header,其值为 cookie 里的 csrftoken 的值

Django 里如何使用 CSRF 防护

  • 首先,最基本的原则是:GET 请求不要用有副作用。也就是说任何处理 GET 请求的代码对资源的访问都一定要是“只读“的。
  • 要启用 django.middleware.csrf.CsrfViewMiddleware 这个中间件
  • 再次,在所有的 POST 表单元素时,需要加上一个 {% csrf_token %} tag
  • 在渲染模块时,使用 RequestContext。RequestContext 会处理 csrf_token 这个 tag,  从而自动为表单添加一个名为 csrfmiddlewaretoken 的 input

在Django 中对csrf 的防范

Django中自带了防止csrf攻击的功能,但对于初学者来说可能不知道如何使用,并给自己带来些意外的麻烦。

例如:一个正常的表单提交操作却总是报错。

Django 中GET请求不需要csrf认证,post请求需要正确的认证才能得到正确的返回结果。

我们先处理一下对表单提交的 csrf 验证问题:一般在POST表单中加入{% csrf_token %}

<form method="POST" action="#">
{% csrf_token %}
  <input name='password' value='用户密码'>
</form>

加入了这句话后,再次提交post表单就不会出现问题了。

或者是另一个思路:禁用csrf 

不过这样可能带来的危害你自己要想清楚了。

全局禁用:settings文件中找到关于csrf的中间件,直接注释。

针对性禁用:在表单提交的对应视图函数上加上一个装饰器 @csrf_exempt

——————————————————————

{% csrf_token %} 实际上是一个模板语法,将项目的token值写入到前端页面的表单中,这个值在建立django项目时就已经自动生成,可以在setting中看到。

——————————————————————?

下面再看一下Ajax调用时的处理方式

在使用 jquery 的 ajax 或者 post 之前可以加入一段 js 代码

jQuery(document).ajaxSend(function(event, xhr, settings) {
  function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
      var cookies = document.cookie.split(';');
      for (var i = 0; i < cookies.length; i++) {
        var cookie = jQuery.trim(cookies[i]);
        // Does this cookie string begin with the name we want?
        if (cookie.substring(0, name.length + 1) == (name + '=')) {
          cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
          break;
        }
      }
    }
    return cookieValue;
  }
  function sameOrigin(url) {
    // url could be relative or scheme relative or absolute
    var host = document.location.host; // host + port
    var protocol = document.location.protocol;
    var sr_origin = '//' + host;
    var origin = protocol + sr_origin;
    // Allow absolute or scheme relative URLs to same origin
    return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
      (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
      // or any other URL that isn't scheme relative or absolute i.e relative.
      !(/^(\/\/|http:|https:).*/.test(url));
  }
  function safeMethod(method) {
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
  }

  if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
    xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
  }
});

或者是直接在模板文件中写入

$.ajaxSetup({
  data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});

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

Python 相关文章推荐
Python利用Beautiful Soup模块修改内容方法示例
Mar 27 Python
python写一个md5解密器示例
Feb 23 Python
Python中.join()和os.path.join()两个函数的用法详解
Jun 11 Python
python十进制和二进制的转换方法(含浮点数)
Jul 07 Python
Python 实现交换矩阵的行示例
Jun 26 Python
python如何实现从视频中提取每秒图片
Oct 22 Python
python字典setdefault方法和get方法使用实例
Dec 25 Python
对python中return与yield的区别详解
Mar 12 Python
Keras 在fit_generator训练方式中加入图像random_crop操作
Jul 03 Python
python 爬取免费简历模板网站的示例
Sep 27 Python
分布式全文检索引擎ElasticSearch原理及使用实例
Nov 14 Python
解决pytorch 数据类型报错的问题
Mar 03 Python
Python正则表达式指南 推荐
Oct 09 #Python
详解Django的CSRF认证实现
Oct 09 #Python
浅析python中的迭代与迭代对象
Oct 08 #Python
实例讲解python中的序列化知识点
Oct 08 #Python
实例讲解python中的协程
Oct 08 #Python
详解python分布式进程
Oct 08 #Python
python中多个装饰器的执行顺序详解
Oct 08 #Python
You might like
PHP3 safe_mode 失效漏洞
2006/10/09 PHP
《PHP编程最快明白》第七讲:php图片验证码与缩略图
2010/11/01 PHP
php从完整文件路径中分离文件目录和文件名的方法
2015/03/13 PHP
iOS+PHP注册登录系统 PHP部分(上)
2016/12/26 PHP
js获取单元格自定义属性值的代码(IE/Firefox)
2010/04/05 Javascript
Javascript实现简单二级下拉菜单实例
2014/06/15 Javascript
jquery实现平滑的二级下拉菜单效果
2015/08/26 Javascript
jQuery.cookie.js实现记录最近浏览过的商品功能示例
2017/01/23 Javascript
mui开发中获取单选按钮、复选框的值(实例讲解)
2017/07/24 Javascript
JavaScript如何实现元素全排列实例代码
2019/05/14 Javascript
jquery+css实现Tab栏切换的代码实例
2019/05/14 jQuery
小程序如何使用分包加载的实现方法
2019/05/22 Javascript
vue远程加载sfc组件思路详解
2019/12/25 Javascript
node.JS事件机制与events事件模块的使用方法详解
2020/02/06 Javascript
vue element-ul实现展开和收起功能的实例代码
2020/11/25 Vue.js
[36:02]DOTA2上海特级锦标赛D组小组赛#2 Liquid VS VP第一局
2016/02/28 DOTA
[01:20]DOTA2上海特级锦标赛现场采访:谁的ID最受青睐
2016/03/25 DOTA
[01:04:49]KG vs LGD 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
python求crc32值的方法
2014/10/05 Python
Python使用pip安装报错:is not a supported wheel on this platform的解决方法
2018/01/23 Python
Python 调用PIL库失败的解决方法
2019/01/08 Python
Python中单线程、多线程和多进程的效率对比实验实例
2019/05/14 Python
关于Python3 类方法、静态方法新解
2019/08/30 Python
Python lambda表达式filter、map、reduce函数用法解析
2019/09/11 Python
python 使用建议与技巧分享(四)
2020/08/18 Python
Python如何急速下载第三方库详解
2020/11/02 Python
Python xlwings插入Excel图片的实现方法
2021/02/26 Python
蔻驰英国官网:COACH英国
2020/07/19 全球购物
美国床垫连锁店:Mattress Firm
2021/02/13 全球购物
小学美术教学反思
2014/02/01 职场文书
激情洋溢的毕业生就业求职信
2014/03/15 职场文书
服务质量承诺书
2014/03/27 职场文书
优秀教师个人材料
2014/12/15 职场文书
2015重阳节座谈会主持词
2015/07/30 职场文书
redis 查看所有的key方式
2021/05/07 Redis
MySQL系列之八 MySQL服务器变量
2021/07/02 MySQL