问题:如何禁用Django的CSRF验证?
我已经在中注释掉了csrf处理器和中间件产品线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 )
但是,当我使用Ajax发送请求时,Django仍然会响应“ csrf令牌不正确或丢失”,并且在将X-CSRFToken添加到标头后,请求将会成功。
这里发生了什么 ?
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 ?
回答 0
如果只需要一些视图而不使用CSRF,则可以使用@csrf_exempt
:
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def my_view(request):
return HttpResponse('Hello world')
您可以在Django文档中找到更多示例和其他场景:
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:
回答 1
要为基于类的视图禁用CSRF,以下对我有用。
使用Django 1.10和python 3.5.2
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
@method_decorator(csrf_exempt, name='dispatch')
class TestView(View):
def post(self, request, *args, **kwargs):
return HttpResponse('Hello world')
To disable CSRF for class based views the following worked for me.
Using django 1.10 and python 3.5.2
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
@method_decorator(csrf_exempt, name='dispatch')
class TestView(View):
def post(self, request, *args, **kwargs):
return HttpResponse('Hello world')
回答 2
在setting.py
MIDDLEWARE中,您可以简单地删除/注释此行:
'django.middleware.csrf.CsrfViewMiddleware',
In setting.py
in MIDDLEWARE you can simply remove/comment this line:
'django.middleware.csrf.CsrfViewMiddleware',
回答 3
对于Django 2:
from django.utils.deprecation import MiddlewareMixin
class DisableCSRF(MiddlewareMixin):
def process_request(self, request):
setattr(request, '_dont_enforce_csrf_checks', True)
必须settings.MIDDLEWARE
在适当的时候(例如在您的测试设置中)添加该中间件。
注意:不再调用该设置MIDDLEWARE_CLASSES
。
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.
回答 4
答案可能不合适,但希望对您有帮助
class DisableCSRFOnDebug(object):
def process_request(self, request):
if settings.DEBUG:
setattr(request, '_dont_enforce_csrf_checks', True)
使用这样的中间件有助于调试请求并检查生产服务器中的csrf。
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.
回答 5
这里的问题是SessionAuthentication执行自己的CSRF验证。这就是为什么即使在注释CSRF中间件的情况下也出现CSRF丢失错误的原因。您可以在每个视图中添加@csrf_exempt,但是如果您想禁用CSRF并为整个应用进行会话身份验证,则可以添加一个额外的中间件,如下所示:
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
我在myapp / middle.py中创建了该类,然后在Middleware的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',
]
可以在Django 1.11上使用DRF
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
回答 6
如果要在“全局”中禁用它,则可以编写自定义中间件,如下所示
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)
然后将该类添加youappname.middlewarefilename.DisableCsrfCheck
到MIDDLEWARE_CLASSES
列表中,然后django.middleware.csrf.CsrfViewMiddleware
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
回答 7
回答 8
@WoooHaaaa一些第三方程序包使用’django.middleware.csrf.CsrfViewMiddleware’中间件。例如,我使用django-rest-oauth,即使禁用了这些东西,我也遇到了类似您的问题。也许这些软件包像我的案例一样响应了您的请求,因为您使用了身份验证修饰符之类的东西。
@WoooHaaaa some third party packages use ‘django.middleware.csrf.CsrfViewMiddleware’ middleware. for example i use django-rest-oauth and i have problem like you even after disabling those things. maybe these packages responded to your request like my case, because you use authentication decorator and something like this.