如何禁用 Django 的 CSRF 验证?

我在 settings.py中注释掉了 csrf 处理器和中间件行:

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 之后,请求将成功。

这是怎么回事?

148159 次浏览

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

from django.views.decorators.csrf import csrf_exempt


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

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

CSRF 可以在视图级实施,即 无法在全球范围内禁用

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

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

这个答案可能不太合适,但我希望能对你有所帮助

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

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

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

在 MIDDLEWARE 的 setting.py中,你可以简单地删除/注释这一行:

'django.middleware.csrf.CsrfViewMiddleware',

如果您想在 Global 中禁用它,您可以编写一个自定义中间件,如下所示

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之前

这里的问题是 SessionAuthentication 执行自己的 CSRF 验证。这就是为什么即使在注释 CSRF 中间件时也会出现 CSRF 缺失错误的原因。 你可以给每个视图添加@CSRF _ free,但是如果你想禁用 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/midle.py 中创建了这个类 然后在 Middleware 的 setings.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

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

在使用此解决方案之前,请阅读 这个链接来自文档


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

  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',
    ]
    ...