@Csrf_Exempt Does Not Work on Generic View Based Class

@csrf_exempt does not work on generic view based class

As @knbk said, this is the dispatch() method that must be decorated.

Since Django 1.9, you can use the method_decorator directly on a class:

from django.utils.decorators import method_decorator

@method_decorator(csrf_exempt, name='dispatch')
class ChromeLoginView(View):

def get(self, request):
return JsonResponse({'status': request.user.is_authenticated()})

def post(self, request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return JsonResponse({'status': True})
return JsonResponse({'status': False})

This avoids overriding the dispatch() method only to decorate it.

Django @csrf_exempt not working in class View

I found out the way to solve this. You need to create a middleware that calls before any Session Middlewares and then check against your desired urls or app to exempt the CSRF token validation. So, the code would be like this:

settings.py

MIDDLEWARE_CLASSES = [
'api.middleware.DisableCSRF', # custom middleware for API
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'a9.utils.middleware.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'a9.core.access.middleware.AccessMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
]

urls.py

app_name = "api"

urlpatterns = [
url(r'^v1/', include([
url(r'^', include(router.urls)),
url(r'^auth/', MyAuthentication.as_view()),
url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')),
url(r'^admin/', include(admin.site.urls)),
])),
]

csrf_disable.py

from django.core.urlresolvers import resolve
# django2


class DisableCSRF(object):
"""Middleware for disabling CSRF in an specified app name.
"""

def process_request(self, request):
"""Preprocess the request.
"""
app_name = "api"
if resolve(request.path_info).app_name == app_name:
setattr(request, '_dont_enforce_csrf_checks', True)
else:
pass # check CSRF token validation

This will only check CSRF token against a specific app or url without removing all the CSRF. Also, this is django-rest-framework independent :)

Django CSRF Verifcation failed - Class based views

This is because is class_based views you need to decorate the dispatch method for csrf_exempt to work

class UserCreate(View):
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super(UserCreate, self).dispatch(request, *args, **kwargs)

def post():
....

Django Rest Framework remove csrf

Note: Disabling CSRF is unsafe from security point of view. Please use your judgement to use the below method.

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.



Related Topics



Leave a reply



Submit