CSRF失败:CSRF令牌丢失或不正确

时间:2022-02-24 04:53:36

I'm using Django 1.7 and django-rest-framework.

我使用Django 1.7和Django -rest框架。

I made an API that returns me some JSON data putting this in my settings.py

我创建了一个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',
    )
}

When I make GET calls, it returns me all the data, but when I try with PUT/PATCH I get:

当我拨打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."}
---------------------------------

This only happens when I am logged in, if I am anonymous I can PUT/PATCH correctly.

这只有在我登录时才会发生,如果我是匿名的,我可以正确地放置/补丁。

I have tried with @csrf_exempt and I got errors, I have included the rest_framework.permissions.AllowAny in the setting...

我尝试了@ csrf_豁免权,但我有错误,我包含了rest_framework.permissions。在设置AllowAny…

I have no idea what's going on. Does anyone know what the issue is?

我不知道发生了什么事。有人知道是什么问题吗?

3 个解决方案

#1


36  

When you are using SessionAuthentication, you are using Django's authentication which usually requires CSRF to be checked. Django REST Framework enforces this, only for SessionAuthentication, so you must pass the CSRF token in the X-CSRFToken header.

在使用SessionAuthentication时,使用的是Django的身份验证,通常需要检查CSRF。Django REST框架强制这样做,只用于SessionAuthentication,所以必须在X-CSRFToken头中传递CSRF令牌。

The Django documentation provides more information on retrieving the CSRF token using jQuery and sending it in requests. The CSRF token is saved as a cookie called csrftoken that you can retrieve from a HTTP response, which varies depending on the language that is being used.

Django文档提供了关于使用jQuery检索CSRF令牌并在请求中发送它的更多信息。CSRF令牌被保存为一个名为csrftoken的cookie,您可以从HTTP响应中检索它,该响应根据所使用的语言而变化。

If you cannot retrieve the CSRF cookie, this is usually a sign that you should not be using SessionAuthentication. I recommend looking into TokenAuthentication or OAuth 2.0 depending on your needs.

如果您不能检索CSRF cookie,这通常是您不应该使用SessionAuthentication的标志。我建议根据您的需要研究TokenAuthentication或OAuth 2.0。

#2


2  

I had similar problem, I've wrapped my URLs under csrf_exempt method as -

我遇到了类似的问题,我把我的url包装在csrf_豁免权方法作为-

from django.views.decorators.csrf import csrf_exempt

url(r'^api/v1/some-resource$', csrf_exempt(SomeApiView.as_view())),

#3


0  

This is what i did to solve it, i included csrf token to the form and using jquery/ javascrip got the csrf token like this when document loaded

这就是我解决它的方法,我将csrf令牌包含到表单中,并使用jquery/ javascrip在装载文档时获得这样的csrf令牌

var $crf_token = $('[name="csrfmiddlewaretoken"]').attr('value');

the included it on jquery headers as follow

它包含在jquery header中,如下所示

 $.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")
            }
        });

#1


36  

When you are using SessionAuthentication, you are using Django's authentication which usually requires CSRF to be checked. Django REST Framework enforces this, only for SessionAuthentication, so you must pass the CSRF token in the X-CSRFToken header.

在使用SessionAuthentication时,使用的是Django的身份验证,通常需要检查CSRF。Django REST框架强制这样做,只用于SessionAuthentication,所以必须在X-CSRFToken头中传递CSRF令牌。

The Django documentation provides more information on retrieving the CSRF token using jQuery and sending it in requests. The CSRF token is saved as a cookie called csrftoken that you can retrieve from a HTTP response, which varies depending on the language that is being used.

Django文档提供了关于使用jQuery检索CSRF令牌并在请求中发送它的更多信息。CSRF令牌被保存为一个名为csrftoken的cookie,您可以从HTTP响应中检索它,该响应根据所使用的语言而变化。

If you cannot retrieve the CSRF cookie, this is usually a sign that you should not be using SessionAuthentication. I recommend looking into TokenAuthentication or OAuth 2.0 depending on your needs.

如果您不能检索CSRF cookie,这通常是您不应该使用SessionAuthentication的标志。我建议根据您的需要研究TokenAuthentication或OAuth 2.0。

#2


2  

I had similar problem, I've wrapped my URLs under csrf_exempt method as -

我遇到了类似的问题,我把我的url包装在csrf_豁免权方法作为-

from django.views.decorators.csrf import csrf_exempt

url(r'^api/v1/some-resource$', csrf_exempt(SomeApiView.as_view())),

#3


0  

This is what i did to solve it, i included csrf token to the form and using jquery/ javascrip got the csrf token like this when document loaded

这就是我解决它的方法,我将csrf令牌包含到表单中,并使用jquery/ javascrip在装载文档时获得这样的csrf令牌

var $crf_token = $('[name="csrfmiddlewaretoken"]').attr('value');

the included it on jquery headers as follow

它包含在jquery header中,如下所示

 $.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")
            }
        });