我使用Django 1.7和Django的REST的框架。
我做了我返回一些JSON数据把这个在我settings.py
的API
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.AllowAny',),
'DEFAULT_RENDERER_CLASSES': (
# 'rest_framework.renderers.XMLRenderer',
'rest_framework.renderers.JSONRenderer',
# 'rest_framework.renderers.BrowsableAPIRenderer',
)
}
当我做GET调用,它返回我所有的数据,但是当我试图用PUT / PATCH我得到:
--------Response Headers---------
Status Code: 403
Date: Wed, 29 Oct 2014 18:51:42 GMT
Vary: Cookie
Server: WSGIServer/0.1 Python/2.7.8
Allow: GET, POST, PUT, PATCH, HEAD, OPTIONS
X-Frame-Options: SAMEORIGIN
Content-Type: application/json
---------------------------------
--------Response Body-----------
{"detail": "CSRF Failed: CSRF token missing or incorrect."}
---------------------------------
这只是发生在我登录的,如果我是匿名的,我可以正确PUT / PATCH。
我曾尝试与@csrf_exempt
和我的错误,我已经包括在设置中,rest_framework.permissions.AllowAny
...
我不知道发生了什么事。有谁知道是什么问题?
当您使用SessionAuthentication,您正在使用Django的认证通常需要CSRF进行检查。 Django的REST框架强制执行此,只为SessionAuthentication
,所以你必须通过CSRF令牌在X-CSRFToken
头。
该Django documentation提供检索CSRF令牌使用jQuery和请求发送它的更多信息。该CSRF令牌被保存为一个cookie称为csrftoken
,你可以从HTTP响应,这取决于正在使用的语言检索。
如果你不能检索CSRF的cookie,这通常是你不应该使用SessionAuthentication
的标志。我建议考虑TokenAuthentication或OAuth 2.0根据您的需要。
这是我做过什么来解决这个问题,我包括CSRF令牌的形式和使用jquery /的javascrip得到了CSRF令牌这样当文件加载
var $crf_token = $('[name="csrfmiddlewaretoken"]').attr('value');
在包括它的jquery标题如下
$.ajax({
type: "POST",
url: "/api/endpoint/",
data: newEndpoint,
headers:{"X-CSRFToken": $crf_token},
success: function (newEnd) {
console.log(newEnd);
add_end(newEnd);
},
error: function () {
alert("There was an error")
}
});
我有类似的问题,我已经包裹着我的下csrf_exempt
方法网址作为 -
from django.views.decorators.csrf import csrf_exempt
url(r'^api/v1/some-resource$', csrf_exempt(SomeApiView.as_view())),
我们有这个问题,它原来是邮差的错。他们被自动发送,我们并没有通过在头csrftoken
和sessionid
默认值。按照本教程帮着解决这个问题:https://avilpage.com/2019/02/django-tips-csrf-token-postman-curl.html
我有一个类似的问题,我会包裹着csrf_exempt
的意见,并仍然遇到错误。原来,我得到的URL错误,因此它被解析为一个“找不到”回调(这是不是从CSRF除外),并因此抛出异常之前我可以告诉的网址是错误的。
// USING AJAX TO UPDATE DATABASE THROUGH REST API
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;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
得到的cookie令牌:
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
var csrftoken = readCookie('csrftoken');
发送令牌头POST请求:
this.$http.post(server,{params: {foo: 'bar'}}, {headers: {"X-CSRFToken":csrftoken }}).then(function (response) {
this.response = response.data;
},
function (response) {
console.log(response);
});
当您承载Apache服务器上Django的网站。与TokenAuthentication和SessionAuthentication Djando REST框架将得到
CSRF失败:CSRF令牌丢失或不正确
为了解决这个问题打开Apache的配置文件 - httpd.conf中添加以下行:
WSGIPassAuthorization On