Django 2.0 学习(22):Django CSRF
Django CSRF
CSRF攻击过程

攻击说明:
1.用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登陆网站A;
2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登陆网站A成功,可以正常发送请求到网站A;
3.用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
4.网站B收到用户请求后,返回一些攻击性代码,并发出一个请求,要求访问第三方站点A;
5.浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。
CSRF的攻击之所以会成功是因为服务器端身份验证机制可以通过Cookie保证一个请求是来自于某个用户的浏览器,>单无法保证该请求是用户允许的。因此,预防CSRF攻击简单可行的方法就是在客户端网页上添加随机数,在服务器>端进行随机数验证,以确保该请求是用户允许的。Django也是通过这个方法来预防CSRF攻击的。
Django防御CSRF攻击
原理
在客户端页面上天机csrftoken,服务器端进行验证。服务器端验证的工作通过"django.middleware.csrf.CsrfViewMiddleware"这个中间件来完成。在Django中防御csrf攻击的方式有两种:
- 在表单中附加csrftoken;
- 通过request请求中添加x-csrftoken请求头;
注意:Django默认对所有的POST请求都进行csrftoken验证,若验证失败则返回403错误。Django中设置防跨站请求伪造功能分为全局和局部。
全局:中间件 django.middleware.csrf.CsrfViewMiddleware
局部:from django.views.decorators.csrf import csrf_protect, csrf_exempt
- @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件;
- @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件;
当用post提交数据的时候,django会去检查是否有一个csrf的随机字符串,如果没有就会报错,错误如下:

在Django内部支持生成这个随机字符串。
通过form提交
在form表单里面需要添加{% csrf_token %},这样当查看页面源码的时候,可以看到form中有一个input是隐藏的:

原理总结:
当用户访问login页面的时候,会生成已给csrf的随机字符串,并且cookie中野村放了这个随机字符串,当用户再次提交数据的时候会带着这个随机字符串提交,如果没有这个随机字符串则无法提交成功。cookie中存放的csrftoken如下图所示:

通过ajax提交
因为cookie中同样存在csrftoken,所以可以在JavaScript中通过$.cookie("csrftoken")获取。如果通过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_CSRFTOEKN是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 %};
Django 2.0 学习(22):Django CSRF的更多相关文章
- Django 2.0 学习(07):Django 视图(进阶-续)
接Django 2.0 学习(06):Django 视图(进阶),我们将聚焦在使用简单的表单进行处理和精简代码. 编写简单表单 我们将用下面的代码,来替换之前的detail模板("polls ...
- Django 2.0 学习(04):Django数据库
数据库设置/配置 打开mysite/settings.py,我们会发现Django是用的是默认的数据库SQLite,如下图所示: Django也是支持其它数据库的,比如PostgreSQL.MySQL ...
- Django 2.0 学习(12):Django 模板语法
Django 模板语法 一.模板 只要是在html里面有模板语法就不是html文件了,这样的文件就叫做模板. 二.模板语法 模板语法变量:{{ }} 在Django模板中遍历复杂数据结构的关键是句点字 ...
- Django 2.0 学习
Django django是基于MTV结构的WEB框架 Model 数据库操作 Template 模版文件 View 业务处理 在Python中安装django 2.0 1 直接安装 pip inst ...
- Django 2.0 学习(19):Django 分页器
Django 分页器 要使用Django实现分页功能,必须从Django中导入Paginator模块(painator - 分页器) views.py from django.shortcuts im ...
- Django 2.0 学习(08):Django 自动化测试
编写我们的第一个测试 确定bug 幸运的是,在polls应用中存在一个小小的bug急需修复:无论Question的发布日期是最近(最后)的日期,还是将来很多天的日期,Question.was_publ ...
- Django 2.0 学习(06):Django 视图(进阶)
概述 Django中的特方法,该方法代表了Django的Web页面,并且视图具有特定的模板.以博客应用为例进行说明,在博客应用中应该包含下面的视图: 博客主页:显示最近的一些记录: 详细页面:单个详细 ...
- Django 2.0 学习(03):Django视图和URL(下)
接上篇博文,继续分析Django基本流程. 编写第一个(view)视图函数 1.打开文件polls/views.py,输入下面的Python代码: from django.http import Ht ...
- Django 2.0 学习(01):Django初识与安装
Django(Python Web框架) Django是一个开放源代码的Web框架,用Python写的.采用了MTV的框架模式,即模型M,模板T和视图V.它最初被开发是用来管理以新闻内容为主的网站,即 ...
随机推荐
- X5webview完美去掉分享功能和缓存功能(2)
前段时间比较忙,没有来得及写完如何将X5WEBVIEW分享功能和缓存功能屏蔽,下面直接来干货,上代码. 1.首先在布局文件中增加一个全屏的布局, <!-- 视频全屏--> <Fram ...
- Git使用教程(一)---本地git管理
之前写过不少小demo,因为没有很好的整理,很多demo都找不到了,必要的时候又要重新写这些demo:这是一个很头疼的问题,很烦躁.网上看到git的版本控制以及托管,很nice.开始学习使用git,关 ...
- 执行sh脚本报“/usr/bin/env: "sh\r": 没有那个文件或目录”错误
出现这个错误的原因是出错的语句后面多了“\r”这个字符,换言之,脚本文件格式的问题,我们只需要把格式改成unix即可: vi xx.sh :set ff :set ff=unix :wq!
- python图像处理(1)图像的打开与保存
使用python进行图像处理时有三种库可以使用分别是:PIL.matplotlib.pyplot.opencv(opencv未接触) 注意:matplotlib读取进来的图片是unit8,0-255范 ...
- 《Python 网络爬虫权威指南》 分享 pdf下载
链接:https://pan.baidu.com/s/1ZYEinjOwM_5dBIVftN42tg 提取码:1om6
- ios手机处理keyup事件时的兼容性问题
在安卓手机中没有任何问题,但在ios手机中出现当输入法中输入内容时,事件keyup没有效果 解决办法: //keyup的兼容性处理 var bind_name = 'input'; if (navig ...
- 半年收入超2亿RMB 独立游戏开发者的艰苦创业路
一款叫做<监狱建筑师>的模拟经营游戏,目前在Steam平台获得了3000万美元(近2亿元)以上的收入.这款游戏由英国独立工作室Introversion Software发布,而团队最困难的 ...
- [Paper Reading] Image Captioning using Deep Neural Architectures (arXiv: 1801.05568v1)
Main Contributions: A brief introduction about two different methods (retrieval based method and gen ...
- SharpDevelop 笔记
1. 下载地址: http://jaist.dl.sourceforge.net/project/sharpdevelop/ 2. 使用 VS2012 去掉编译不通过的 Test ,其它可以运行调试. ...
- 前端_html
目录 HTML介绍 标签说明 常用标签 <!DOCTYPE>标签 <head>内常用标签 <body>内常用标签 特殊字符 其他:各种各样的标签 HTML的规范 H ...