Django Rest Framework remove csrf Django Rest Framework remove csrf django django

Django Rest Framework remove csrf


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, BasicAuthentication 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.


Easier solution:

In views.py, use django-braces' CsrfExemptMixin and authentication_classes:

# views.pyfrom rest_framework.views import APIViewfrom rest_framework.response import Responsefrom django.views.decorators.csrf import csrf_exemptfrom braces.views import CsrfExemptMixinclass Object(CsrfExemptMixin, APIView):    authentication_classes = []    def post(self, request, format=None):        return Response({'received data': request.data})


Modify urls.py

If you manage your routes in urls.py, you can wrap your desired routes with csrf_exempt() to exclude them from the CSRF verification middleware.

import viewsfrom django.conf.urls import patterns, urlfrom django.views.decorators.csrf import csrf_exempturlpatterns = patterns('',    url(r'^object/$', csrf_exempt(views.ObjectView.as_view())),    ...)

Alternatively, as a DecoratorSome may find the use of the @csrf_exempt decorator more suitable for their needs

for instance,

from django.views.decorators.csrf import csrf_exemptfrom django.http import HttpResponse@csrf_exemptdef my_view(request):    return HttpResponse('Hello world')

should get the Job Done!