Django Rest框架删除cs

2024-04-25 01:54:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道有关于Django Rest框架的答案,但是我找不到解决问题的方法。

我有一个应用程序,它有身份验证和一些功能。 我添加了一个新的应用程序,它使用了Django Rest框架。我只想在此应用程序中使用库。另外,我想提出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只有这个应用程序?


Tags: djangofrompyimport框架rest应用程序url
3条回答

为什么会发生这种错误?

这是因为DRF使用了默认的SessionAuthentication方案。DRF的SessionAuthentication使用Django的会话框架进行身份验证,这需要检查CSRF。

当您没有在视图/视图集中定义任何authentication_classes时,DRF使用此身份验证类作为默认类。

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

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

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

那该怎么办?

现在要禁用csrf检查,可以创建一个自定义身份验证类CsrfExemptSessionAuthentication,该类扩展自默认的SessionAuthentication类。在这个身份验证类中,我们将重写在实际的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错误。

更简单的解决方案:

在views.py中,使用大括号CsrfExemptMixin和authentication\u类:

# 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})

修改url.py

如果在urls.py中管理路由,则可以使用csrf_exempt()包装所需的路由,以将它们从csrf验证中间件中排除。

from django.conf.urls import patterns, url
    from django.views.decorators.csrf import csrf_exempt
    import views

urlpatterns = patterns('',
    url(r'^object/$', csrf_exempt(views.ObjectView.as_view())),
    ...
)

或者,作为一个装饰师 有些人可能会发现使用@csrf_exempt decorator更适合他们的需要

例如

from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')

应该完成任务!

相关问题 更多 >