Django Tastypie总是返回401未经授权

时间:2014-05-15 09:31:13

标签: jquery python ajax django tastypie

我对我的tastypie资源使用ajax请求,但即使我使用SessionAuthentication()和DjangoAuthorization(),它也总是401。

resources.py

class EventsResource(ModelResource):

user = fields.ForeignKey(UserResource, 'user')

    class Meta:
        queryset = Event.objects.all()
        resource_name = 'events'
        filtering = {'start': ALL,
                     'end':ALL
                     }
        list_allowed_methods = ['get', 'post','put', 'patch']
        detail_allowed_methods = ['get', 'post', 'put', 'delete']
        authentication = SessionAuthentication()
        authorization = Authorization()
        include_resource_uri = True
        limit = 0
        always_return_data = True

这是日历的资源,所以我有一个事件模型,我的ajax请求是在django-admin中加载的javascript文件中;我还检查了请求标头是否有csrf令牌和会话ID,但它不起作用。

.ajax({
                    url:  event.resource_uri,
                    dataType: 'json',
                    contentType: 'application/json; encode=UTF-8',
                    type: 'DELETE',
                    success: function () {
                        $calendar.fullCalendar('removeEvents');
                        $calendar.fullCalendar('refetchEvents');
                        $('#modal-confirm').modal('hide');
                        showmsg('Evento eliminato correttamente', 'warning');
                    }
                });

2 个答案:

答案 0 :(得分:1)

您正在使用SessionAuthentication但尚未提供CSRF令牌标头(我看到您已检查过它,但它未出现在您的代码中)。

在包含JavaScript的页面中的某处包含{% csrf_token %}标记,然后使用X-CSRF-Token选项修改您的AJAX方法以设置beforeSend标题:

$.ajax({
    url:  event.resource_uri,
    dataType: 'json',
    contentType: 'application/json; encode=UTF-8',
    type: 'DELETE',
    beforeSend: function(jqXHR) {
        jqXHR.setRequestHeader('X-CSRFToken', $('input[name=csrfmiddlewaretoken]').val());
    },
    success: function () {
        $calendar.fullCalendar('removeEvents');
        $calendar.fullCalendar('refetchEvents');
        $('#modal-confirm').modal('hide');
        showmsg('Evento eliminato correttamente', 'warning');
    }
});

答案 1 :(得分:0)

您应该在每次POST请求时将CSRF令牌作为POST数据传递。 CSRF令牌的推荐来源来自cookie,如下所示:

getCookie: function(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = $.trim(cookies[i]);
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

然后,您将在AJAX请求中设置标题,如下所示:

var csrftoken = this.getCookie('csrftoken');
//Use Setup prior or use the beforeSend on the fly 
/*$.ajaxSetup({
    beforeSend: function(xhr, settings) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
    }
});*/
$.ajax({
    type: "POST",
    dataType: "json",
    contentType: "application/json",
    url: "/my/uri/",
    data: {"any": "thing"},
    beforeSend: function(xhr, settings) {
        xhr.setRequestHeader("X-CSRFToken", csrftoken);
    },
    success: function(data) {
        console.log("Weeey") ;
    }
});

参考:https://docs.djangoproject.com/en/1.8/ref/csrf/#ajax