Django的CSRF检查失败与一个Ajax POST请求 [英] Django CSRF check failing with an Ajax POST request

查看:204
本文介绍了Django的CSRF检查失败与一个Ajax POST请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以通过我的AJAX后使用一些帮助与Django的CSRF保护机制规定。我已经按照指示在这里:

I could use some help complying with Django's csrf protection mechanism via my AJAX post. I've followed the directions here:

<一个href="http://docs.djangoproject.com/en/dev/ref/contrib/csrf/">http://docs.djangoproject.com/en/dev/ref/contrib/csrf/

我复制了这些样本AJAX code,他们有一个页面上的完全相同:

I've copied the AJAX sample code they have on that page exactly:

<一个href="http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax">http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

我把警报的xhr.setRequestHeader调用之前打印的getCookie的内容(csrftoken'),它的确是填充了一些数据。我不知道如何验证令牌是正确的,但我鼓舞的是,它的发现和送点东西。

I put an alert printing the contents of getCookie('csrftoken') before the xhr.setRequestHeader call and it is indeed populated with some data. I'm not sure how to verify that the token is correct, but I'm encouraged that it's finding and sending something.

不过在Django仍然拒绝我的AJAX职务。

But django is still rejecting my AJAX post.

下面是我的javascript:

Here's my Javascript:

$.post("/memorize/", data, function (result) {
    if (result != "failure") {
        get_random_card();
    }
    else {
        alert("Failed to save card data.");
    }
});

下面是我从Django的看到的错误:

Here's the error I'm seeing from Django:

[23 /二月/ 2011 22点08分29秒]POST /记忆/ HTTP / 1.1403 2332

[23/Feb/2011 22:08:29] "POST /memorize/ HTTP/1.1" 403 2332

我敢肯定,我想的东西,或许这很简单,但我不知道它是什么。我已搜索周围的SO,看到有关关闭CSRF检查通过csrf_exempt装饰我的观点的一些信息,但是我发现没有吸引力。我已经试过了出来,它的工作原理,但我宁愿让我的岗位上班的路上Django的目的是要想到吧,如果可能的话。

I'm sure I'm missing something, and maybe it's simple, but I don't know what it is. I've searched around SO and saw some information about turning off the CSRF check for my view via the csrf_exempt decorator, but I find that unappealing. I've tried that out and it works, but I'd rather get my POST to work the way Django was designed to expect it, if possible.

以防万一,这是有帮助的,这里的主旨是什么我的看法是这样做的:

Just in case it's helpful, here's the gist of what my view is doing:

def myview(request):

    profile = request.user.profile

    if request.method == 'POST':
        """
        Process the post...
        """
        return HttpResponseRedirect('/memorize/')
    else: # request.method == 'GET'

        ajax = request.GET.has_key('ajax')

        """
        Some irrelevent code...
        """

        if ajax:
            response = HttpResponse()
            profile.get_stack_json(response)
            return response
        else:
            """
            Get data to send along with the content of the page.
            """

        return render_to_response('memorize/memorize.html',
                """ My data """
                context_instance=RequestContext(request))

感谢您的答复!

Thanks for your replies!

推荐答案

真正的解决办法

好吧,我设法追查问题了。它位于Javascript的(我建议以下)code。

Ok, I managed to trace the problem down. It lies in the Javascript (as I suggested below) code.

您需要的是这样的:

$.ajaxSetup({ 
     beforeSend: function(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;
         }
         if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
             // Only send the token to relative URLs i.e. locally.
             xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
         }
     } 
});

而不是code贴在官方文档: <一href="http://docs.djangoproject.com/en/1.2/ref/contrib/csrf/#ajax">http://docs.djangoproject.com/en/1.2/ref/contrib/csrf/#ajax

instead of the code posted in the official docs: http://docs.djangoproject.com/en/1.2/ref/contrib/csrf/#ajax

工作code,来源于此的Django条目:<一href="http://www.djangoproject.com/weblog/2011/feb/08/security/">http://www.djangoproject.com/weblog/2011/feb/08/security/

The working code, comes from this Django entry: http://www.djangoproject.com/weblog/2011/feb/08/security/

所以,一般的解决方法是:用它代替ajaxSend处理器ajaxSetup处理程序。我不知道为什么它的工作原理。但它的工作对我来说:)

So the general solution is: "use ajaxSetup handler instead of ajaxSend handler". I don't know why it works. But it works for me :)

previous后(无答案)

我遇到了同样的问题其实。

I'm experiencing the same problem actually.

这发生后 - 有在Django的1.2.4 AJAX POST请求没有错误(AJAX是不以任何方式保护,但它的工作就好了)

It occurs after updating to Django 1.2.5 - there were no errors with AJAX POST requests in Django 1.2.4 (AJAX wasn't protected in any way, but it worked just fine).

就像OP,我已经试过了JavaScript片段张贴在Django文档。我使用jQuery 1.5。我还使用了django.middleware.csrf.CsrfViewMiddleware中间件。

Just like OP, I have tried the JavaScript snippet posted in Django documentation. I'm using jQuery 1.5. I'm also using the "django.middleware.csrf.CsrfViewMiddleware" middleware.

我试图按照中间件code,我知道,它不能对这样的:

I tried to follow the the middleware code and I know that it fails on this:

request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')

然后

if request_csrf_token != csrf_token:
    return self._reject(request, REASON_BAD_TOKEN)

这个如果是真的,因为request_csrf_token是空的。

this "if" is true, because "request_csrf_token" is empty.

基本上,这意味着头未设置。那么,有什么不对这个js行:

Basically it means that the header is NOT set. So is there anything wrong with this JS line:

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

我希望,提供详细信息将帮助我们解决这个问题:)

I hope that provided details will help us in resolving the issue :)

这篇关于Django的CSRF检查失败与一个Ajax POST请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆