Django中间件使用ajax使用HTTPS POST抛出403错误

时间:2012-08-14 02:02:06

标签: ajax django post https django-csrf

我是这里很多人的新手(Django / Ajax等),所以虽然我理解高级CSFR图片,但我没有完整处理细节。

由于传递的数据量较大,我需要将请求从GET转换为PUT。高级别,我正在通过HTTPS对django应用程序进行AJAX POST API调用。呼叫是从提供页面的同一域进行的。

但是,我一直收到'CSRF cookie not set'错误。

我正在使用Django 1.4

为了通过CSRF保护,我在标题中包含了其他帖子中提到的X-CSFRToken,并在发布的数据中包含了{{csrf_token}}标记。但是,它看起来不像标记被标记替换。 X-CSFRToken值在请求中作为NULL发送。不确定为什么它没有设置。

我的印象是我不需要在页面视图中使用ensure_csrf_cookie(),因为我在ajaxSetup中获取了POST之前的cookie,但我也试过了。

想法我做错了什么?

相关代码:

siteUrl = "https://localhost:8443/"

$.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]);
                 if (cookie.substring(0, name.length + 1) == (name + '=')) {
                     cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                     break;
                 }
             }
         }
         return cookieValue;
         }
         if (new RegExp("^"+siteUrl.replace("\\","\\\\")+".*").test(settings.url)) {
             // Only send the token to URLs from our site.
             xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
         }
     } 
});


$.ajax({
    url: submitUrl,
    data: {'network_ids': JSON.stringify(network_ids),
            'csrfmiddlewaretoken': '{{ csrf_token }}'},
    type: 'POST',
    crossDomain: true,
    dataType: 'json',
    cotentType: 'application/json',
    success: function(mydata) {
        console.log(mydata);
    },
    error: function(jqXHR, textStatus, errorThrown) {alert(textStatus); alert(errorThrown)}
})

2 个答案:

答案 0 :(得分:1)

您有几种选择: 此代码清单显示您从cookie获取CSRF令牌:https://docs.djangoproject.com/en/dev/ref/contrib/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;
}
getCookie('csrftoken');

并假设javascript函数正在提交到django视图,您可以告诉该视图忽略csrf保护。 https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#django.views.decorators.csrf.csrf_exempt

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')

答案 1 :(得分:0)

你的js是通过Django的模板引擎提供的吗?否则将不会评估{{ csrf_token }}。您是否检查过它实际上已发布到服务器?

同样根据docs ajaxSend事件背后的想法是必须明确传递csrf_token

我注意到您的ajaxSetup与文档中的{{1}}略有不同。这可能是正确的,但我会从文档中复制原文。