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与CSRF 、AJAX的更多相关文章

  1. Django 的 CSRF 保护机制

    转自:http://www.cnblogs.com/lins05/archive/2012/12/02/2797996.html 用 django 有多久,我跟 csrf 这个概念打交道就有久了. 每 ...

  2. Django 的 CSRF 保护机制(转)

    add by zhj:假设用户登录了网站A,而在网站B中有一个CSRF攻击标签,点击这个标签就会访问网站A,如果前端数据(包括sessionid)都放在本地存储的话, 当在网站B点击CSRF攻击标签时 ...

  3. Python自动化之Django的CSRF

    什么CSRF? CSRF, Cross Site Request Forgery, 跨站点伪造请求.举例来讲,某个恶意的网站上有一个指向你的网站的链接,如果 某个用户已经登录到你的网站上了,那么当这个 ...

  4. Django之CSRF 跨站请求伪造

    一.简介 1.点我了解什么是跨站请求伪造 2.django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对 ...

  5. Django之csrf防御机制

    1.csrf攻击过程 csrf攻击说明: 1.用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A; 2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站 ...

  6. django之CSRF

    在POST请求到达views之前,csrf帮我们进行一层验证 <!DOCTYPE html> <html lang="en"> <head> & ...

  7. python框架之Django(9)-CSRF

    准备 现有如下模板和视图: <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...

  8. django基础 -- 7.Ajax

    一.ajax 的特点 1.异步交互:客户端发出一个请求后,需要等待服务器响应结束后, 才能发出第二个请求 2.局部刷新:给用户的感受是在不知不觉中完成请求和响应过程. 二.ajax 模板示例 ($.a ...

  9. django中的ajax组件

    目录 django中的ajax 向服务器发送请求的途径 Ajax的特点 基于jquery实现的ajax请求 利用ajax实现计算器 利用ajax实现登陆认证 利用form表单进行文件上传 利用ajax ...

随机推荐

  1. windows无法远程连接linux

    网络模式 修改对应的NAT模式,子网地址的前三位要与window,internet协议版本里的IP地址的前三位一致.

  2. kali linux下 hachcat安装

    网上关于hachcat的简单使用方法介绍很多,然而却很少有在kali linux上的安装教程,找了好长时间,终于安装成功了,特此将中间借鉴的内容记录如下: #首先安装p7z,用于解压下载的p7z包 # ...

  3. Django的View

    一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. ...

  4. django 上传文件及反馈信息

    from django.shortcuts import render,HttpResponse from django.views import View from Fiskars.models i ...

  5. php 获取网站根目录

    方法1(需自行调整根目录): define('BASE_PATH',str_replace('\\','/',realpath(dirname(__FILE__).'/'))."/" ...

  6. oracle merge同时包含增、删、改

    原来一直没注意,merge是可以支持delete,只不过必须的是on条件满足,也就是要求系统支持逻辑删除,而非物理删除. Using the DELETE Clause with MERGE Stat ...

  7. glibc 2.x release note

    glibc 2.x release note,参见: https://sourceware.org/glibc/wiki/Glibc%20Timeline https://www.gnu.org/so ...

  8. Vue 旅游网首页开发1-工具安装及码云使用

    Vue 旅游网首页开发-工具安装及码云使用 环境安装 安装 node.js node.js 官网:https://nodejs.org/en/ 注册码云,创建私密仓库存储项目 码云:https://g ...

  9. 一条命令,根据进程名判断有进程输出up,无进程无输出

    这个研究了好一会, 由于开发需要,提供的命令. shell命令,可以按照分号分割,也可以按照换行符分割.如果想一行写入多个命令,可以通过“';”分割. a=`ps -ef | grep nginx | ...

  10. 20145320《网络对抗》逆向及Bof基础实践

    1 逆向及Bof基础实践说明 1.1 实践目标 本次实践的对象是一个名为pwn20145320的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的 ...