How to disable Django's CSRF validation?
PythonDjangoPython Problem Overview
I have commented out csrf processor and middleware lines in settings.py
:
122
123 TEMPLATE_CONTEXT_PROCESSORS = (
124 'django.contrib.auth.context_processors.auth',
125 # 'django.core.context_processors.csrf',
126 'django.core.context_processors.request',
127 'django.core.context_processors.static',
128 'cyathea.processors.static',
129 )
130
131 MIDDLEWARE_CLASSES = (
132 'django.middleware.common.CommonMiddleware',
133 'django.contrib.sessions.middleware.SessionMiddleware',
134 # 'django.middleware.csrf.CsrfViewMiddleware',
135 'django.contrib.auth.middleware.AuthenticationMiddleware',
136 'django.contrib.messages.middleware.MessageMiddleware',
137 'django.middleware.locale.LocaleMiddleware',
138 # Uncomment the next line for simple clickjacking protection:
139 # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
140 )
But when I use Ajax to send a request, Django still respond 'csrf token is incorrect or missing', and after adding X-CSRFToken to headers, the request would succeed.
What is going on here ?
Python Solutions
Solution 1 - Python
If you just need some views not to use CSRF, you can use @csrf_exempt
:
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def my_view(request):
return HttpResponse('Hello world')
You can find more examples and other scenarios in the Django documentation:
Solution 2 - Python
To disable CSRF for class-based views, the following worked for me.
I'm using Django 1.10 and Python 3.5.2
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
@method_decorator(csrf_exempt, name='dispatch')
class TestView(View):
def post(self, request, *args, **kwargs):
return HttpResponse('Hello world')
Solution 3 - Python
In setting.py
in MIDDLEWARE you can simply remove/comment this line:
'django.middleware.csrf.CsrfViewMiddleware',
Solution 4 - Python
The problem here is that SessionAuthentication performs its own CSRF validation. That is why you get the CSRF missing error even when the CSRF Middleware is commented. You could add @csrf_exempt to every view, but if you want to disable CSRF and have session authentication for the whole app, you can add an extra middleware like this -
class DisableCSRFMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
setattr(request, '_dont_enforce_csrf_checks', True)
response = self.get_response(request)
return response
I created this class in myapp/middle.py Then import this middleware in Middleware in settings.py
MIDDLEWARE = [
'django.middleware.common.CommonMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',
'myapp.middle.DisableCSRFMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
That works with DRF on django 1.11
Solution 5 - Python
For Django 2:
from django.utils.deprecation import MiddlewareMixin
class DisableCSRF(MiddlewareMixin):
def process_request(self, request):
setattr(request, '_dont_enforce_csrf_checks', True)
That middleware must be added to settings.MIDDLEWARE
when appropriate (in your test settings for example).
Note: the setting isn't not called MIDDLEWARE_CLASSES
anymore.
Solution 6 - Python
The answer might be inappropriate, but I hope it helps you
class DisableCSRFOnDebug(object):
def process_request(self, request):
if settings.DEBUG:
setattr(request, '_dont_enforce_csrf_checks', True)
Having middleware like this helps to debug requests and to check csrf in production servers.
Solution 7 - Python
If you want disable it in Global, you can write a custom middleware, like this
from django.utils.deprecation import MiddlewareMixin
class DisableCsrfCheck(MiddlewareMixin):
def process_request(self, req):
attr = '_dont_enforce_csrf_checks'
if not getattr(req, attr, False):
setattr(req, attr, True)
then add this class youappname.middlewarefilename.DisableCsrfCheck
to MIDDLEWARE_CLASSES
lists, before django.middleware.csrf.CsrfViewMiddleware
Solution 8 - Python
CSRF can be enforced at the view level, which can't be disabled globally.
In some cases this is a pain, but um, "it's for security". Gotta retain those AAA ratings.
https://docs.djangoproject.com/en/dev/ref/csrf/#contrib-and-reusable-apps
Solution 9 - Python
this link from documentation
Before using this solution, please readI solved this problem with the following two steps:
-
Add this class to an
utils.py
file:from <your-project-name> import settings class DisableCSRF(MiddlewareMixin): def process_request(self, request): if settings.DEBUG: setattr(request, '_dont_enforce_csrf_checks', True)
-
And in the
settings.py
file, add above middleware to theMIDDLEWARE
list:... MIDDLEWARE = [ ... 'django.middleware.csrf.CsrfViewMiddleware', ... '<path-of-utils.py>.utils.DisableCSRF', ] ...