问题描述
我知道有关于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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!