跨站请求伪造(csrf)中间件整理
一. CSRF中间件
字面意思跨站请求伪造; 即模仿个请求朝服务器发送,django中对跨站伪造的请求有相应的校验
from django.views.decorators.csrf import csrf_exempt, csrf_protect
csrf_exempt 给单个视图排除校验,以装饰器形式给某个视图加上,则该视图就不会进行校验
局部禁用的前提是全局有校验
csrf_protect 给单个视图必须校验,以装饰器形式给某个视图加上,则该视图就必须进行校验
即使注释调settings中的46行也必须得校验. 局部使用的前提是全局没有校验
二. csrt源码解析其校验的本质大概流程是:
1. 在process_request内,从请求的cookie中获取csrftoken的值,保存为scrf_token
2. 在process_view内:
> 如果视图函数加上了csrf_exempt的装饰器 不做校验
> 如果请求方式是'GET', 'HEAD', 'OPTIONS', 'TRACE' 也不做校验
> 其它的请求方式就要进行校验了,校验的实质如下:
1.从request.POST中获取csrfmiddlewaretoken对象的值
2.从请求头中获取csrfmiddlewaretoken对象的值
3.用获取到的csrfmiddlewaretoken的值和csrftoken的值做比较,如果校验成功,流程继续;校验不成功
则拒绝; 1和2中只要有1个能获取到csrfmiddlewaretoken的值即可,不用两个中都有.
总结: 两点要求,1.浏览器必须带有cookie; 2. post请求体中或请求头中要能获取到csrfmiddlewaretoken值
三.针对以上总结的两点,做相应的处理,处理办法如下
确保浏览器带有cookie的两种方式:
> 在form表单内加入{% csrf_token %}
> 不使用{% csrf_token %},导入from django.views.decorators.csrf import ensure_csrf_cookie
将ensure_csrf_cookie以装饰器形式加在视图上,保证返回的相应有cookie
确保能从post请求体中或请求头信息中获取到csrfmiddlewaretokende的方式:
> 页面中加入{% csrf_token %}标签
1.获取标签值,加入post请求体中, csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val()
2.获取标签值,加入post请求头中, headers: {"X-CSRFToken": $('[name="csrfmiddlewaretoken"]').val()}
> 上面1或2都是给单个的ajax请求加csrfmiddlewaretokende,这里再介绍个通过引入js文件形式
给全局所有ajax头部加入csrfmiddlewaretokende的办法,代码思路如下: (万能办法)
1.通过django官网提供的代码来实现,首先项目下static文件夹内新建js文件,复制以下代码:
2.以script标签在html页面导入新建的这个a.js文件, <script src=’/static/a.js’></script>
它的作用是给每个请求头信息上加crsfmiddlewaretoken信息
猜测: 引入js文件形式可同时让浏览器带cookie和让请求头带crsfmiddlewaretoken信息,因为使用
CBV写ajax文件上传时,html中没加{%csrf_token%},views中也没用ensure_csrf_token装饰器
四. js文件代码如下:
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; } var csrftoken = getCookie('csrftoken'); 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); } } });
最新文章
- 11 个很少人知道但很有用的 Linux 命令
- 几个功能强大的系统源码(机票分销、机票预订、OA、手机充值、wifi营销、网络超市、体检平台)
- Java lamda Stream
- ACM题目————zoj问题
- 3.29考试(HNOI难度)
- HDU 1171(01背包)
- 关于linux下零散的东西 --慢慢补充
- Obstack是C标准库里面对内存管理的GNU扩展
- inux平台的C与C++
- JS中实现A*算法寻路
- unity3D学习序幕
- angular localStorage使用方法
- makefile中伪目标的理解
- javascript同步分页
- js实现放大效果
- Hibernate使用sql语句实现多表关联查询
- jcifs windows 域账户单点登录(转)
- SummerNote 富文本编辑器 - Rails 集成
- 免费网络视频监控软件cmsclient
- SOA面向服务的架构
热门文章
- “System.OutOfMemoryException”类型的未经处理的异常在 mscorlib.dll 中发生
- CopyTranslator-复制即翻译的外文辅助阅读翻译解决方案
- java——栈和队列 面试题
- RF脚本中的坑1: SyntaxError: invalid token
- mm_struct简要解析
- DOM(一):节点层次-Node类型
- SecureCRT 设置
- Token的概念
- 第13章 	GPIO-位带操作—零死角玩转STM32-F429系列
- JavaScript_DOM学习篇_图片切换小案例