Django Tastypie 总是返回401未授权
我正在使用ajax请求来访问我的tastypie资源,但即使我使用了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
你应该在每次发送POST请求时,把CSRF令牌作为POST数据传递。推荐的CSRF令牌来源是从cookies中获取,像这样:
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") ;
}
});
1
你正在使用 SessionAuthentication
,但是没有提供 CSRF 令牌头(我看到你检查过这个,但在你的代码中没有找到)。
在包含你 JavaScript 的页面中,某个地方加上 {% csrf_token %}
标签,然后修改你的 AJAX 方法,使用 beforeSend
选项来设置一个 X-CSRF-Token
头:
$.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');
}
});