@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
How to Improve My Paw Detection
How to Set a Default Value for a Wtforms Selectfield
How to Install the Yaml Package for Python
How to Reduce the Image File Size Using Pil
Mixing Cdef and Regular Python Attributes in Cdef Class
Tuple or List When Using 'In' in an 'If' Clause
Positional Argument Follows Keyword Argument
Pandas Groupby.Size VS Series.Value_Counts VS Collections.Counter with Multiple Series
Python JSON.Loads Fails with 'Valueerror: Invalid Control Character At: Line 1 Column 33 (Char 33)'
Differencebetween Join and Merge in Pandas
Set Up Python Simplehttpserver on Windows
Bin Size in Matplotlib (Histogram)
How to Use a String as a Keyword Argument
Multithreaded Web Server in Python
Open Cv Error: (-215) Scn == 3 || Scn == 4 in Function Cvtcolor