Django跨站伪造请求保护措施设置方法

阅读更多

在django建站中遇到post提交表单提示403错误, 发现以Post方式提交表单会触发django内置的csrf保护机制,并且在403页面给出了解决方法,根据提示更改后发现问题依旧,网上查阅很多同学的解决方案均不能解决这个问题,所以到官网上查阅了关于csrf部分的具体设置,最后成功解决了这个问题。

 

官方csrf部分设置翻译:

CSRF设置步骤:

第一步: 在settings.py中的MIDDLEWARE_CLASSES部分添加'django.middleware.csrf.CsrfViewMiddleware',如果使用普通方式创建的django项目,这一项一般都已经存在了不用额外设置。

 如果你不希望加入csrf的中间件,那么可以在views中的方法上加上csrf_protect()装饰器方法,这一步不是必须设置的,网上很多有很多人都在启用了中间件的同时也加上了csrf_protect()方法,导致问题依旧,官方文档上明确写到了这一步是【Alternatively】

 

第二步:在POST表单的template中加入csrf_token。这一步很简单,在模板中添加如下代码:

{% csrf_token %}

 需要注意的一点是,表单提交路径是如果是外部链接则不需要添加csrf token。

 

第三步:在请求处理方法中添加context processor。

这一步有两种方式实现:

  方法1:使用RequestContext,RequestContext始终都使用了'django.core.context_processors.csrf'。 If you are using generic views or contrib apps, you are covered already, since these apps use RequestContext throughout.(这一段还没搞明白,大致意思猜想是普通views或内置的contrib下的应用时,那么已经使用了这种方式来处理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)

    在第一次按照自己的设想将如上代码加入到view中时,发现问题依旧,后来将前两行代码放置在方法开始位置后,成功解决问题,由此推测该示例代码的前两行只能放在第一次使用request对象之前。

 

django中使用Ajax请求的CSRF设置:

将官方文档上的ajax设置照搬下来:

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) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
    crossDomain: false, // obviates need for sameOrigin test
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type)) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

 这里使用的是jQuery,于是可以使用jQuery来正常发送ajax请求,如:

$(document).ready(function(){
        $("#postBtn").click(function(){
            $.post('/ajax/aPost/', {id:'0001'}, function(data){
                 alert(data);
            })
        });
    }
);

 get请求就不赘述了,同理,本文主要问题在于设置csrf说明,使用django版本为1.4.3,jQuery版本为1.8.0

你可能感兴趣的:(django,csrf,ajax,json)