我正在使用Django 1.7和django-rest-framework。
我创建了一个API,它会返回一些JSON数据,并将其放入我的settings.py
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
包含在设置中...
我不知道发生了什么。有谁知道这是什么问题?
答案 0 :(得分:59)
当您使用SessionAuthentication时,您正在使用Django的身份验证,通常需要检查CSRF。 Django REST Framework仅针对SessionAuthentication
强制执行此操作,因此您必须在X-CSRFToken
标头中传递CSRF令牌。
Django documentation提供了有关使用jQuery检索CSRF令牌并在请求中发送它的更多信息。 CSRF令牌保存为名为csrftoken
的cookie,您可以从HTTP响应中检索该cookie,该响应因使用的语言而异。
如果您无法检索CSRF Cookie,则通常表明您不应使用SessionAuthentication
。我建议根据您的需要调查TokenAuthentication或OAuth 2.0。
答案 1 :(得分:4)
这就是我解决它的问题,我在表单中包含了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")
}
});
答案 2 :(得分:3)
我认为这是一个cookie问题。
永久解决方案:如果您使用的是邮递员,请首先通过单击“ X”清除现有的cookie。然后添加正确的cookie。
临时解决方案(用于调试):在您的settings.py
中尝试:
'DEFAULT_AUTHENTICATION_CLASSES': [
# 'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
]
答案 3 :(得分:2)
我遇到了类似问题,我已将csrf_exempt
方法下的网址包裹为 -
from django.views.decorators.csrf import csrf_exempt
url(r'^api/v1/some-resource$', csrf_exempt(SomeApiView.as_view())),
答案 4 :(得分:2)
我们遇到了这个问题,事实证明这是邮递员的错。他们自动发送了csrftoken
和sessionid
默认值,我们没有在标头中传递它们。遵循本教程有助于解决该问题:https://avilpage.com/2019/02/django-tips-csrf-token-postman-curl.html
答案 5 :(得分:1)
答案 6 :(得分:1)
// 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);
}
}
});
答案 7 :(得分:1)
这发生在我使用邮递员测试 rest-auth 注册时 发生这种情况是因为邮递员发送了不正确的标头,一些旧的 cookie 和错误的内容类型,我认为这是某种错误,或者我错了
解决方案:所以我禁用了默认标题
手动输入内容类型和json正文(POST请求)
然后重新启用所需的标头
答案 8 :(得分:0)
从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);
});
答案 9 :(得分:0)
我有一个类似的问题,我用csrf_exempt
包装了视图,但仍然遇到错误。原来,我把URL弄错了,所以它解决了一个“未找到”的回调(这不是CSRF的豁免),因此在我被告知URL错误之前抛出了一个异常。 >
答案 10 :(得分:0)
当您在Apache服务器上托管django网站时。 带有TokenAuthentication和SessionAuthentication的Djando rest框架将获得
CSRF失败:CSRF令牌丢失或不正确
要修复此打开的Apache配置文件-httpd.conf,请添加以下行:
WSGIPassAuthorization On
答案 11 :(得分:0)
我在here上找到了解决此错误的最简单方法。它非常适合我。
步骤:
继承SessionAuthentication类:
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
class CsrfExemptSessionAuthentication(SessionAuthentication):
def enforce_csrf(self, request):
return # To not perform the csrf check previously happening
然后在您创建的APIView中执行以下操作:
class Object(APIView):
authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication)
def post(self, request, format=None):
这将使您保持登录状态,并且将不再为此APIView检查CSRF令牌。
答案 12 :(得分:0)
在 settings.py 文件中
INSTALLED_APPS = [
...
...
...
...
'rest_framework.authtoken',
...
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
}
在项目 urls.py 中
from rest_framework.authtoken import views
urlpatterns = [
....
path('api-token-auth/',views.obtain_auth_token,name='api-token-auth')
]
打开终端
$ pip3 install httpie
$ python3 manage.py createsuperuser # if not created
$ http POST http://localhost:8000/api-token-auth/ username="username" password = "password" # You will get token key (Just copy it) ex:a243re43fdeg7r4rfgedwe89320
<块引用>
<块引用>
您的令牌密钥也将自动保存在您的数据库中
转到邮递员标题(如示例中所示) 例如:screenshot from postman ,where and how to paste accessed toke
然后插入您的令牌密钥。
<块引用>答案 13 :(得分:-5)
django1.8 python2.7
color = ['Red', 'Green', 'White']
我通过使用其他http方法来修复它; 哦,我再次面对它,这次是因为我粘贴了它,里面有一些看不见的字符