138

我在以下代码中注释掉了 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 token 不正确或丢失”,并且将 X-CSRFToken 添加到 headers 后,请求会成功。

这里发生了什么 ?

4

9 回答 9

281

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

from django.views.decorators.csrf import csrf_exempt

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

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

于 2013-05-09T09:10:17.460 回答
51

要为基于类的视图禁用 CSRF,以下对我有用。

我正在使用 Django 1.10 和 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')
于 2016-10-12T07:57:10.347 回答
49

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

'django.middleware.csrf.CsrfViewMiddleware',
于 2017-03-28T08:36:13.857 回答
21

这里的问题是 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 中创建了这个类,然后在 settings.py 中的 Middleware 中导入这个中间件

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

于 2017-12-19T14:04:32.287 回答
17

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

于 2017-12-22T13:07:41.237 回答
12

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

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

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

于 2015-06-04T08:50:56.720 回答
8

如果你想在全局中禁用它,你可以编写一个自定义中间件,像这样

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

于 2017-05-08T07:24:43.383 回答
1

CSRF 可以在视图级别强制执行,不能全局禁用

在某些情况下,这很痛苦,但嗯,“这是为了安全”。必须保留那些AAA评级。

https://docs.djangoproject.com/en/dev/ref/csrf/#contrib-and-reusable-apps

于 2015-04-02T05:31:54.967 回答
0

在使用此解决方案之前,请阅读文档中的此链接


我通过以下两个步骤解决了这个问题:

  1. 将此类添加到utils.py文件中:

    from <your-project-name> import settings
    class DisableCSRF(MiddlewareMixin):
       def process_request(self, request):
          if settings.DEBUG:
             setattr(request, '_dont_enforce_csrf_checks', True)
    
  2. 并在settings.py文件中,将上述中间件添加到MIDDLEWARE列表中:

    ...
    MIDDLEWARE = [
        ...
        'django.middleware.csrf.CsrfViewMiddleware',
        ...
        '<path-of-utils.py>.utils.DisableCSRF',
    ]
    ...
    
于 2022-01-16T17:30:29.630 回答