第六章:Django 综合篇 - 17:CSRF与AJAX
CSRF(Cross-site request forgery)跨站请求伪造,是一种常见的网络攻击手段,具体内容和含义请大家自行百度。
Django为我们提供了防范CSRF攻击的机制。
一、基本使用
默认情况下,使用django-admin startproject xxx命令创建工程时,CSRF防御机制就已经开启了。如果没有开启,请在MIDDLEWARE设置中添加'django.middleware.csrf.CsrfViewMiddleware'。
对于GET请求,一般来说没有这个问题,CSRF通常是针对POST方法的!
在含有POST表单的模板中,需要在其<form>表单元素内部添加csrf_token标签,如下所示:
<form action="" method="post">
{% csrf_token %}
....
</form>
这样,当表单数据通过POST方法,发送到后台服务器的时候,除了正常的表单数据外,还会携带一个CSRF令牌随机字符串,用于进行csrf验证。其实没有多么麻烦和复杂,对么?如果表单中没有携带这个csrf令牌,你将会获得一枚403奖章。
额外提示:对于初学者,要明白一件事情,就是我们上面讲的都是Django项目自己内部的事务,不涉及与外界的关系。例如,你不能把上面那个表单发往百度,百度会懵逼的,你这发的啥?其次,那样也不安全,可能引起CSRF信息泄露而导致自己的站点出现漏洞。
二、 AJAX
我们知道,在前端的世界,有一种叫做AJAX的东西,也就是“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),经常被用来在不刷新页面的情况下,提交和请求数据。如果我们的Django服务器接收的是一个通过AJAX发送过来的POST请求的话,那么将很麻烦。
为什么?因为AJAX中,没有办法像form表单中那样携带{% csrf_token %}令牌。
那怎么办呢?
好办!在你的前端模版的JavaScript代码处,添加下面的代码:
// using jQuery
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) {
// 这些HTTP方法不要求CSRF包含
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
上面代码的作用就是让你的ajax的POST方法带上CSRF需要的令牌,它依赖Jquery库,必须提前加载Jquery。这是Django官方提供的解决方案哦,-。
三、装饰器
1. 单独指定csrf验证需要
有时候,我们在全站上关闭了CSRF功能,但是希望某些视图还有CSRF防御,那怎么办呢?
Django为我们提供了一个csrf_protect(view)装饰器,使用起来非常方便,如下所示:
from django.views.decorators.csrf import csrf_protect
from django.shortcuts import render
@csrf_protect
def my_view(request):
c = {}
# ...
return render(request, "a_template.html", c)
现在,虽然全站关掉了csrf,但是my_view视图依然需要进行csrf验证。
2. 单独指定忽略csrf验证
有正就有反。在全站开启CSRF机制的时候,有些视图我们并不想开启这个功能。比如,有另外一台机器通过requests库,模拟HTTP通信,以POST请求向我们的Django主机服务器发送过来了一段保密数据。它无法携带CSRF令牌,必然会被403。
这怎么办呢?
在接收这个POST请求的视图上为CSRF开道口子,不进行验证。这就需要使用Django为我们提供的csrf_exempt(view)装饰器了,下面是使用范例:
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
@csrf_exempt
def my_view(request):
return HttpResponse('Hello world')
这下POST数据是没问题了,但是又带来了新的安全问题,需要你自己处理。
3. 确保csrf令牌被设置
Django还提供了一个装饰器,确保被装饰的视图在返回页面时同时将csrf令牌一起返回。
这个装饰器是:ensure_csrf_cookie(view),其使用方法和上面的一样:
from django.views.decorators.csrf import ensure_csrf_cookie
from django.http import HttpResponse
@ensure_csrf_cookie
def my_view(request):
return HttpResponse('Hello world')
4. requires_csrf_token(view)
这个装饰器类似csrf_protect,一样要进行csrf验证,但是它不会拒绝发送过来的请求。
from django.views.decorators.csrf import requires_csrf_token
from django.shortcuts import render
@requires_csrf_token
def my_view(request):
c = {}
# ...
return render(request, "a_template.html", c)
第六章:Django 综合篇 - 17:CSRF与AJAX的更多相关文章
- 第六章Django
web应用程序 server端建立socket,不断地accept,当收到客户端连接信号之后,服务端向客户端发送数据,将html网页打开,read出来,并发送至客户端,这样客户端就可以浏览到网页的内容 ...
- 《Django By Example》第六章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:无他,祝大家年会都中奖!) 第六章 ...
- Testlink1.9.17使用方法(第六章 测试计划制定)
第六章 测试计划制定 QQ交流群:585499566 在TestLink系统中,一个完整的测试计划包括:集成测试阶段.系统测试阶段. 一. 创建测试计划 1,点击主页上[测试计划管理] 2,在“测试计 ...
- 第二十二章 Django会话与表单验证
第二十二章 Django会话与表单验证 第一课 模板回顾 1.基本操作 def func(req): return render(req,'index.html',{'val':[1,2,3...]} ...
- 《Python核心编程》 第六章 序列 - 课后习题
课后习题 6–1.字符串.string 模块中是否有一种字符串方法或者函数可以帮我鉴定一下一个字符串是否是另一个大字符串的一部分? 答:成员关系操作符(in.not in) import string ...
- Gradle 1.12 翻译——第十六章. 使用文件
有关其它已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或訪问:http://gradledoc.qiniudn.com ...
- 第十六章——处理锁、阻塞和死锁(3)——使用SQLServer Profiler侦测死锁
原文:第十六章--处理锁.阻塞和死锁(3)--使用SQLServer Profiler侦测死锁 前言: 作为DBA,可能经常会遇到有同事或者客户反映经常发生死锁,影响了系统的使用.此时,你需要尽快侦测 ...
- 简学Python第六章__class面向对象编程与异常处理
Python第六章__class面向对象编程与异常处理 欢迎加入Linux_Python学习群 群号:478616847 目录: 面向对象的程序设计 类和对象 封装 继承与派生 多态与多态性 特性p ...
- Java基础知识二次学习--第六章 常用类
第六章 常用类 时间:2017年4月26日16:14:49~2017年4月26日16:56:02 章节:06章_01节~06章_06节 视频长度:20:57+1:15+8:44+1:26+11:2 ...
随机推荐
- 用户数据交互 Scanner
# 用户交互 Scanner ``` java package study5ran2yl.study; import java.util.Scanner; public class demo09 { ...
- HCNP Routing&Switching之DHCP中继
前文我们聊了下BFD相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/16487842.html:今天来聊一聊DHCP中继相关话题: DHCP的作用 DH ...
- zabbix监控添加学习笔记
在实际生产环境中,除了CPU.内存等一些系统信息可以挂载zabbix的自带模板Template OS Linux:但是一些公司开发的定制服务需要自己写模板或者监控项去监控: 一.监控公司的java服务 ...
- StringBuilder的原理
StringBuilder类 字符串拼接问题 由于String类的对象内容不可改变,所以每当进行字符串拼接的时候,总是会在内存中创建一个新的对象.例如: class Test{ public stat ...
- 2019国家集训队论文《整点计数》命题报告 学习笔记/Min25
\(2019\)国家集训队论文<整点计数>命题报告 学习笔记/\(Min25\) 补了个大坑 看了看提交记录,发现\(hz\)的\(xdm\)早过了... 前置知识,\(HAOI\)< ...
- js中数组去重的方法
在实际工作或面试中,我们经常会遇到"数组去重"问题,接下来就是使用js实现的数组去重的多种方法: 1.借助ES6提供的Set结构 var arr = [1,1,2,2,3,3,4, ...
- Mybatis 懒加载使用及源码分析
Mybatis 懒加载的使用 什么是懒加载?懒加载的意思就是在使用的时候才去加载,不使用不去加载,相反的就叫饥饿加载或者立即加载.懒加载在Mybatis中一般是存在与联合查询的情况,比如查询一个对象的 ...
- 渗透攻防Web篇-深入浅出SQL注入
1 背景 京东SRC(Security Response Center)收录大量外部白帽子提交的sql注入漏洞,漏洞发生的原因多为sql语句拼接和Mybatis使用不当导致. 2 手工检测 2.1 前 ...
- [PostgreSql]生产级别数据库安装要考虑哪些问题?
大家好,我是字母哥(coder)! 我让公司的小伙伴写一个生产级别的PostgreSQL的安装文档,结果他和我说:"不是用一个命令就能安装好么?还用写文档么?".我知道他想说的是这 ...
- Jamie and Tree (dfs序 + 最近公共祖先LCA)
题面 题解 我们求它子树的权值和,一般用dfs序把树拍到线段树上做. 当它换根时,我们就直接把root赋值就行了,树的结构不去动它. 对于第二个操作,我们得到的链和根的相对位置有三种情况: 设两点为A ...