Django进阶之CSRF的解决

作者:python修行路 时间:2022-01-30 02:51:27 

简介

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

来源:http://www.cnblogs.com/zhaof/p/6281482.html

标签:Django,CSRF
0
投稿

猜你喜欢

  • python音频处理用到的操作的示例代码

    2021-05-11 22:05:19
  • MYSQL教程:MYSQL字符集支持

    2009-02-27 15:55:00
  • 使用Python来做一个屏幕录制工具的操作代码

    2023-11-02 18:57:40
  • 使用Python webdriver图书馆抢座自动预约的正确方法

    2021-01-26 10:21:07
  • 阿里云ECS服务器部署django的方法

    2023-04-09 10:00:26
  • python+unittest+requests实现接口自动化的方法

    2022-04-10 08:47:38
  • Python项目实战之使用Django框架实现支付宝付款功能

    2021-12-11 23:28:11
  • pytorch 如何实现HWC转CHW

    2023-06-05 21:58:23
  • Python换行与不换行的输出实例

    2022-01-15 13:10:10
  • 浅析Python打包时包含静态文件处理方法

    2023-05-29 01:12:10
  • python绘制带有色块的折线图

    2022-08-11 07:01:58
  • python+django+selenium搭建简易自动化测试

    2022-01-25 06:17:16
  • 网站的新趋势

    2008-12-11 13:36:00
  • 教大家使用Python SqlAlchemy

    2022-12-02 01:40:17
  • selenium+python自动化测试之使用webdriver操作浏览器的方法

    2023-06-28 03:04:47
  • MySQL字段类型说明

    2007-09-27 19:22:00
  • JS的编译和执行顺序

    2009-02-01 18:42:00
  • python包导入的两种方式

    2022-11-25 22:49:30
  • 布同自制Python函数帮助查询小工具

    2021-09-01 19:38:35
  • python manim实现排序算法动画示例

    2021-11-10 10:41:58
  • asp之家 网络编程 m.aspxhome.com