本文介绍了Django Rest Framework删除csrf的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我有一个应用程序具有身份验证和一些功能。
我添加了一个新的应用程序,它使用Django Rest Framework。我只想在这个应用程序中使用库。另外我想要发出POST请求,我总是收到这个回复:

  {
detail:CSRF失败:CSRF令牌丢失或不正确。
}

我有如下代码:

 #urls.py 
from django.conf.urls import patterns,url


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


#views.py
从rest_framework.views导入APIView
从rest_framework.response导入响应
从django.views.decorators.csrf导入csrf_exempt


类对象(APIView):

@csrf_exempt
def post(self,request,format = None):
return响应({'received data':request.data})

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

解决方案

为什么这个错误是发生?



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



当您在视图/视图中未定义任何 authentication_classes 时,DRF会将此认证类用作默认。

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

由于DRF需要支持会话和非会话对同一视图进行身份验证,它只对经过身份验证的用户执行CSRF检查。这意味着只有经过身份验证的请求才需要CSRF令牌,匿名请求可能没有发送CSRF令牌。



如果您使用具有SessionAuthentication的AJAX样式API,则需要为任何不安全HTTP方法调用包括一个有效的CSRF令牌,例如 PUT,PATCH,POST或DELETE 请求。



然后如何处理?



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


从rest_framework.authentication import导入SessionAuthentication 

类CsrfExemptSessionAuthentication(SessionAuthentication):

def enforce_csrf(self,request):
return#不执行以前发生的csrf检查

在您看来,您可以将 authentication_classes 定义为:

  authentication_classes =(CsrfExemptSessionAuthentication,BasicAuthentication)

这应该会处理csrf错误。


I know that there are answers regarding Django Rest Framework, but I couldn't find a solution to my problem.

I have an application which has authentication and some functionality.I added a new app to it, which uses Django Rest Framework. I want to use the library only in this app. Also I want to make POST request, and I always receive this response:

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

I have the following code:

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

I want add the API without affecting the current application.So my questions is how can I disable CSRF only for this app ?

解决方案

Why this error is happening?

This is happening because of the default SessionAuthentication scheme used by DRF. DRF's SessionAuthentication uses Django's session framework for authentication which requires CSRF to be checked.

When you don't define any authentication_classes in your view/viewset, DRF uses this authentication classes as the default.

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

Since DRF needs to support both session and non-session based authentication to the same views, it enforces CSRF check for only authenticated users. This means that only authenticated requests require CSRF tokens and anonymous requests may be sent without CSRF tokens.

If you're using an AJAX style API with SessionAuthentication, you'll need to include a valid CSRF token for any "unsafe" HTTP method calls, such as PUT, PATCH, POST or DELETE requests.

What to do then?

Now to disable csrf check, you can create a custom authentication class CsrfExemptSessionAuthentication which extends from the default SessionAuthentication class. In this authentication class, we will override the enforce_csrf() check which was happening inside the actual SessionAuthentication.

from rest_framework.authentication import SessionAuthentication

class CsrfExemptSessionAuthentication(SessionAuthentication):

    def enforce_csrf(self, request):
        return  # To not perform the csrf check previously happening

In your view, then you can define the authentication_classes to be:

authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication)

This should handle the csrf error.

这篇关于Django Rest Framework删除csrf的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 10:30