Django Rest框架删除csrf

我知道有关于Django Rest Framework的答案,但我找不到解决scheme。

我有一个应用程序具有身份validation和一些function。 我添加了一个新的应用程序,它使用Django Rest Framework。 我只想在这个应用程序中使用库。 另外,我想做POST请求,我总是收到这个回应:

{ "detail": "CSRF Failed: CSRF token missing or incorrect." } 

我有以下代码:

 # urls.py from django.conf.urls import patterns, url urlpatterns = patterns( 'api.views', url(r'^object/$', views.Object.as_view()), ) # views.py from rest_framework.views import APIView from rest_framework.response import Response from django.views.decorators.csrf import csrf_exempt class Object(APIView): @csrf_exempt def post(self, request, format=None): return Response({'received data': request.data}) 

我想添加API而不影响当前的应用程序。 所以我的问题是我怎么能禁用这个应用程序的CSRF?

为什么这个错误发生?

这是由于DRF使用默认的SessionAuthenticationscheme。 DRF的SessionAuthentication使用Django的会话框架进行validation,这需要检查CSRF。

当你没有在view / viewset中定义任何的authentication_classes时,DRF使用这个authentication类作为默认值。

 'DEFAULT_AUTHENTICATION_CLASSES'= ( 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication' ), 

由于DRF需要同时支持基于会话和非基于会话的身份validation,因此只对经过身份validation的用户执行CSRF检查。 这意味着只有经过身份validation的请求才需要CSRF令牌,并且匿名请求可以在没有CSRF令牌的情况下发送。

如果您在使用SessionAuthentication的AJAX风格API,则需要为任何“不安全”的HTTP方法调用(例如PUT, PATCH, POST or DELETE请求)包含有效的CSRF令牌。

那该怎么办?

现在要禁用csrf检查,可以创build一个自定义的authentication类CsrfExemptSessionAuthentication ,该类从默认的SessionAuthentication类扩展。 在这个authentication类中,我们将覆盖实际SessionAuthentication内发生的enforce_csrf()检查。

 from rest_framework.authentication import SessionAuthentication, BasicAuthentication class CsrfExemptSessionAuthentication(SessionAuthentication): def enforce_csrf(self, request): return # To not perform the csrf check previously happening 

在你看来,你可以定义authentication_classes为:

 authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication) 

这应该处理csrf错误。

更简单的解决scheme

在views.py中,使用大括号CsrfExemptMixin和authentication_classes:

 # views.py from rest_framework.views import APIView from rest_framework.response import Response from django.views.decorators.csrf import csrf_exempt from braces.views import CsrfExemptMixin class Object(CsrfExemptMixin, APIView): authentication_classes = [] def post(self, request, format=None): return Response({'received data': request.data}) 

如果您不想使用基于会话的身份validation,则可以从REST_AUTHENTICATION_CLASSES中删除“会话身份validation”,并自动删除所有基于csrf的问题。 但在这种情况下,可浏览的API可能无法正常工作。 此外,即使使用会话身份validation,也不会出现此错误 您应该为您的apis使用像TokenAuthentication这样的自定义身份validation,并确保在您的请求中发送Accept:application/jsonContent-Type:application/json (提供您正在使用json)以及身份validation令牌。

我感到同样的问题。 我跟着这个参考 ,它的工作。 解决scheme是创build一个中间件

在其中一个应用程序中添加disable.py文件(在我的例子中是'myapp')

 class DisableCSRF(object): def process_request(self, request): setattr(request, '_dont_enforce_csrf_checks', True) 

并将MIDDLEWARE添加到MIDDLEWARE_CLASSES

 MIDDLEWARE_CLASSES = ( myapp.disable.DisableCSRF, ) 

您可能正在向可浏览的API发送数据,该数据库预期使用csrf格式。

如果您正在使用API​​,则可能需要发送JSON。 请确保你的头文件中的Content-Type设置为application/json ,它不需要CSRF。

更多的上下文,比如带有标题的请求将有助于给出更准确的答案。

如果您正在为您的应用程序使用独占的虚拟环境,则可以使用以下方法,而无需使用任何其他应用程序。

您观察到的情况是因为rest_framework/authentication.pySessionAuthentication类的authenticate方法中包含以下代码:

 self.enforce_csrf(request) 

如果您不需要CSRF检查,则可以修改Request类以拥有名为csrf_exempt的属性,并在相应的View类csrf_exempt其初始化为True 。 例如:

接下来,修改上面的代码如下:

 if not request.csrf_exempt: self.enforce_csrf(request) 

Request类中有一些相关的更改。 一个完整的实现可以在这里(完整的描述): https : //github.com/piaxis/django-rest-framework/commit/1bdb872bac5345202e2f58728d0e7fad70dfd7ed

对于所有谁没有帮助的答案。 是的,如果您没有使用SessionAuthentication AUTHENTICATION CLASS,DRF会自动删除CSRF保护,例如许多开发人员只使用JWT:

 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', ), 

CSRF not set问题可能会由于某种原因而发生,例如你没有正确添加到你的path中查看:

 url(r'^api/signup/', CreateUserView), # <= error! DRF cant remove CSRF because it is not as_view that does it! 

代替

 url(r'^api/signup/', CreateUserView.as_view()),