如何禁用Django的CSRF验证?


111

我已经在中注释掉了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添加到标头后,请求将会成功。

这里发生了什么 ?


Answers:


232

如果只需要一些视图而不使用CSRF,则可以使用@csrf_exempt

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')

您可以在Django文档中找到更多示例和其他场景:


2
嗨,@ TheBronx,我真的很想知道为什么我的解决方案不起作用。
WoooHaaaa

1
对不起,@ MrROY,我不知道为什么您的解决方案无法正常工作。我只知道它能@csrf_exemp正常工作,因为我最近使用它时就没有问题。希望你找到答案。
Salvatorelab

6
@MrROY,这是Django的东西。大多数事情起作用/不起作用仅仅是因为在代码库的深处有一个神奇的设置。
idursun

2
提醒:如果在同一视图中还有其他装饰器,则该顺序是相关的:因此,请首先放置@csrf_exempt。
Patrick Bassut 2013年

3
嗯-也许是技术上正确的答案,但最肯定不是OP想要的或我一直在寻找的东西。
Danny Staple 2014年

40

要为基于类的视图禁用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')

32

setting.pyMIDDLEWARE中,您可以简单地删除/注释此行:

'django.middleware.csrf.CsrfViewMiddleware',

1
在使用curl作为http客户端的Dj​​ango 2.1上,这对我有效。
粘土

1
@xtrinch确保完全退出/重新启动服务器进程。我认为自动更新不会带来任何变化
基本的

15

对于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


11

答案可能不合适,但希望对您有帮助

class DisableCSRFOnDebug(object):
    def process_request(self, request):
        if settings.DEBUG:
            setattr(request, '_dont_enforce_csrf_checks', True)

使用这样的中间件有助于调试请求并检查生产服务器中的csrf。


嗯 在Django 1.9.1中进行了尝试。从方法中删除了@csrf_exempt装饰器,并添加了上面的代码。因为未设置Cookie,所以得到了403。
Craig S. Anderson

11

这里的问题是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


3
感谢您为问题提供答案,而不仅仅是发布解决方案。
ThaJay

5

如果要在“全局”中禁用它,则可以编写自定义中间件,如下所示

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.DisableCsrfCheckMIDDLEWARE_CLASSES列表中,然后django.middleware.csrf.CsrfViewMiddleware



0

@WoooHaaaa一些第三方程序包使用'django.middleware.csrf.CsrfViewMiddleware'中间件。例如,我使用django-rest-oauth,即使禁用了这些东西,我也遇到了类似您的问题。也许这些软件包像我的案例一样响应了您的请求,因为您使用了身份验证修饰符之类的东西。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.