django CSRF

CSRF引用学习

参考学习:
浅谈CSRF攻击方式
[科普]跨站请求伪造-CSRF防护方法
这是篇关于CSRF的英文权威文档


防御的总结如下:

1、服务器端进行CSRF防御
就是在客户端页面增加伪随机数
或者是表单验证码(就是在客户端页面增加伪随机数,就是对用户而言不方便)
更多的参考以上链接
2、客户端防御的方式就靠用户对安全性的重视程度了。

上面的参考文章示例是基于其他web框架,对于django而言,它为我们解决了这个后顾之忧

Cross Site Request Forgery protection for Django

在Django文档中说的很详尽(点击阅读)
在django中可以通过CsrfViewMiddleware中间件和{% csrf_token %}模版变量很方便的防止csrf攻击。
在django中使用步骤如下:
1、添加中间件
在settings.py的MIDDLEWARE_CLASSES中添加csrf中间件,且必须放在CsrfResponseMiddleware前面。如下:

当然你也可以在view中设置django.views.decorators.csrf.csrf_protect装饰器。
2、在模版中设置
在POST

标签内,放置 {% csrf_token %}
<form action="" method="post">{% csrf_token %}

3、在视图函数中设置
在相应的视图函数中,确保使用django.core.context_processors.csrf,这可以通过两种方式:

1、在RequestContext中使用django.core.context_processors.csrf
2、手动导入和使用处理器生成CSRF令牌并将其添加到模板上下文,如下:

from django.core.context_processors import csrf

from django.shortcuts import render_to_response



def my_view(request):

c = {}

c.update(csrf(request))

# ... view code here

return render_to_response("a_template.html", c)

我们在走完上面的流程发现,出错了。。如下:

原因是在视图函数中少了一个装饰方法@csrf_protect
装饰方法:
而不是增加CsrfViewMiddleware就全面保护,您可以使用csrfprotect装饰,具有完全相同的功能,在特定的视图,需要保护。注意必须通过POST形式和{% csrftoken %}令牌才能对此有用。

AJAX

需要说明一点是,ajax POST请求有点特殊,因为你必须记住通过csrf令牌产生的数据添加到POST数据中,然后POST请求过去。对于这种形式有另一种处理的方法,就是在每个XMLHttpRequest,设置自定义X-CSRFToken头作为CSRF令牌的值。,比如jQuery的ajaxSend.

ajaxSend() 方法在 AJAX 请求开始时执行函数。它是一个 Ajax 事件。
语法:.ajaxSend([function(event,xhr,options)])
其中:
具体见这里

$(document).ajaxSend(function(event, xhr, settings) {

    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;

    }

    function sameOrigin(url) {

        // url could be relative or scheme relative or absolute

        var host = document.location.host; // host + port

        var protocol = document.location.protocol;

        var sr_origin = '//' + host;

        var origin = protocol + sr_origin;

        // Allow absolute or scheme relative URLs to same origin

        return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||

            (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||

            // or any other URL that isn't scheme relative or absolute i.e relative.

            !(/^(\/\/|http:|https:).*/.test(url));

    }

    function safeMethod(method) {

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

    }



    if (!safeMethod(settings.type) && sameOrigin(settings.url)) {

        xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));

    }

});


添加这一个javascript文件,该文件包含在你的网站将确保通过jQuery AJAX POST请求,将不会被CSRF保护。

详尽见文档

 

你可能感兴趣的:(django)