Django 安全之跨站点请求伪造(CSRF)保护

简介: Django 安全之跨站点请求伪造(CSRF)保护

Django 安全之跨站点请求伪造(CSRF)保护



测试环境

Win7

Django 1.11

 

 

跨站点请求伪造(CSRF)保护

中间件配置

默认的CSRF中间件在MIDDLEWARE中定义并处于激活状态。如果需要变更默认配置,修改settings.py中的MIDDLEWARE配置即可,如下,假设要开启CSRF,确保列表包含  'django.middleware.csrf.CsrfViewMiddleware',并且其位置位于其它会对CSRF攻击进行处理的中间件之前,假设要禁用CSRF中间件,去掉列表中的'django.middleware.csrf.CsrfViewMiddleware',或者采用注释方式,把 'django.middleware.csrf.CsrfViewMiddleware' 注释掉。注意:更改配置后需要重启web服务器。

 

MIDDLEWARE = [

   ……,

'django.middleware.csrf.CsrfViewMiddleware',

……

]

 

如果CSRF中间件被禁用(不推荐),又想对特定视图启用中间件保护,则可以针对特定视图使用csrf_protect()修饰器,如下:

from django.views.decorators.csrf import csrf_protect

 

@csrf_protect

def specific_view(request):

   do something

 

参考链接:https://docs.djangoproject.com/en/2.1/ref/csrf/#django.views.decorators.csrf.csrf_protect

 

 

相反的,如果中间件已经开启,但是又不想针对特定视图使用中间件保护,则可以针对特定视图使用csrf_exempt() 修饰器

from django.views.decorators.csrf import csrf_exempt

 

 

@csrf_exempt

def specific_view(request):

do something

 

参考链接:https://docs.djangoproject.com/en/2.1/ref/csrf/#utilities

 

 

html模板配置

开启CSRF中间件的情况下,要在html模板中为使用post方法的form表单新增 csrf_token tag,如下:

 

<form method="post">

{% csrf_token %}

<input ...>... </input>

...

</form>

 

注意:如果被渲染的view视图未使用csrf_token模板标签,Django可能不会设置CSRF token cookie。这种情况下,假如有必要,可以使用Django提供的 @ensure_csrf_cookie()装饰器强制view视图发送CSRF cookie。

 

from django.views.decorators.csrf import ensure_csrf_cookie

 

@ensure_csrf_cookie()

def specific_view(request):

do something

 

view视图函数

对应的视图函数中,确保使用了RequestContext来渲染response,以便{%csrf_token %}可以正常运行。因为 render()函数使用了RequestContext,所以一般的view中,使用render()也是可以的。

 

 

前端js脚本

注意:如果已开启CSRF 的情况下,需要给请求添加X_CSRFTOKEN 请求头,否则会报403错误

/**

* 验证不需要CSRF保护的HTTP方法名(GET|HEAD|OPTIONS|TRACE

*/

function csrfSafeMethod(method) {

return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));

}

 

/**

* 获取cookie项的值

* key:cookie名称

*/

function getCookie(key) {

 

var cookies = document.cookie.split(';'); // 获取每个cookie项(不含会话id)

var value = undefined;

for (var i in cookies) {

var kv = cookies[i].split('='); // 每个cookie项的名称和cookie的值

var temp_key = kv[0].replace(' ', ''); // 获取的cookie项有多个值,第二个开始,键 的值 的左侧会加个空格

if (key == temp_key) {

var value = kv[1];

break;

       }

   }

return value;

}

 

 

/**

* Created by shouke on 2018/11/1.

*/

 

//全局变量设置

var loginURL = '/platform/api/v1/login'; // 注册api地址

var loginFormID = 'login-form';           // 登录表单ID

var registerRightNowID = 'registerRightNow' // 立即注册链接ID

 

/**

* 初始化

*/

$(document).ready(function() {

// 设置顶部导航

setTopNav();

 

var resources = $.session.get('resources');

if (resources) {

resources = JSON.parse(resources).resources;

// 设置立即注册url

$("#" + registerRightNowID).attr("href", resources.register_url.url);

} else {

alert('获取资源失败,导致设置立即注册连接失败');

}

 

// 为登录表单绑定提交事件

$('#' + loginFormID).submit(function() {

/**

        * 提交登录信息

        */

var dataArray = $('#' + loginFormID).serializeArray();

 

var data = {}

$.each(dataArray, function () {

data[this.name] = this.value;

     });

 

var csrfToken = getCookie('csrftoken');

if (csrfToken == undefined) {

alert('获取Cookie失败');

return false;

     }

 

$.ajax({

type: "POST",

url: loginURL,

async: false,

data: data,

beforeSend: function (xhr, settings) {

if (!csrfSafeMethod(settings.type) && !this.crossDomain) {

                   xhr.setRequestHeader("X-CSRFTOKEN", csrfToken);

            }

        },

success: function (result) {

if (result.success == 'true') {

alert(result.msg);

$.session.remove('resources');                // 清空登录前获取的资源,以便重新获取资源

                // 重定向返回登录前的页面

window.location.href = result.next;

           } else {

alert(result.msg + "," + result.reason);

           }

      },

error: function(XmlHttpRequest, textStatus, errorThrown) {

alert('登录请求失败' + XmlHttpRequest.responseText);

      }

   });

return false;

});

});

 

注意:这里最后面添加的return false; 主要是用于 避免跳转到django后台的返回结果数据页

 

 

参考链接

https://docs.djangoproject.com/en/2.1/ref/csrf/#using-csrf

https://docs.djangoproject.com/en/2.1/topics/security/#cross-site-request-forgery-csrf-protection

 

 

目录
相关文章
|
5月前
|
安全 NoSQL Java
互联网并发与安全系列教程(06) - 常见的Web安全漏洞(CSRF攻击)
互联网并发与安全系列教程(06) - 常见的Web安全漏洞(CSRF攻击)
67 0
|
3月前
|
前端开发 数据库 Python
使用 Python 的 Web 框架(如 Django 或 Flask)来建立后端接口,用于处理用户的请求,从数据库中查找答案并返回给前端界面
【1月更文挑战第13天】使用 Python 的 Web 框架(如 Django 或 Flask)来建立后端接口,用于处理用户的请求,从数据库中查找答案并返回给前端界面
86 7
|
8天前
|
存储 中间件 数据安全/隐私保护
Django的CSRF保护机制:保障用户数据安全
【4月更文挑战第15天】Django是一款具有内置CSRF保护的Python Web框架,通过CSRF中间件防止攻击者伪造用户请求。其机制包括:生成并自动添加到表单的CSRF令牌,服务器端的令牌验证以及每个用户会话的唯一令牌存储。为了增强防护,开发者应使用HTTPS,自定义令牌名称,限制跨域请求,并谨慎处理第三方库。Django的CSRF保护与最佳实践结合,能有效保障用户数据安全。
|
1月前
|
安全 数据库 开发工具
Django实战:从零到一构建安全高效的Web应用
Django实战:从零到一构建安全高效的Web应用
48 0
|
2月前
|
安全 数据安全/隐私保护
第二轮学习笔记:CSRF跨站请求伪造漏洞
第二轮学习笔记:CSRF跨站请求伪造漏洞
15 0
|
4月前
|
JSON 前端开发 JavaScript
Django实践-04静态资源和Ajax请求
Django实践-04静态资源和Ajax请求
Django实践-04静态资源和Ajax请求
|
4月前
|
JavaScript Python
django和vue 请求403 FORBIDDEN怎么办
在请求头里,添加X-CSRFToken, 取自浏览器里的cookie 再附上取cookie的源码
35 0
|
5月前
|
数据采集 存储 数据挖掘
Django爬虫:如何处理超过重试次数的请求以保障数据完整性
Django爬虫:如何处理超过重试次数的请求以保障数据完整性
|
5月前
|
数据安全/隐私保护 Python
27 Django高级- Admin站点
27 Django高级- Admin站点
36 0
|
5月前
|
安全 JavaScript 前端开发
22 Django模板 - csrf
22 Django模板 - csrf
26 0