python 如何禁用Django的CSRF验证?

fafcakar  于 2023-03-16  发布在  Python
关注(0)|答案(9)|浏览(126)

我已经注解掉了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 token is correct or missing”(csrf令牌不正确或丢失),并且在将X-CSRFToken添加到消息头后,请求会成功。
这是怎么回事?

ecbunoof

ecbunoof1#

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

from django.views.decorators.csrf import csrf_exempt

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

你可以在Django文档中找到更多的例子和其他场景:

  • https://docs.djangoproject.com/en/dev/ref/csrf/#edge-cases
2ic8powd

2ic8powd2#

在MIDDLEWARE的setting.py中,您可以简单地删除/注解此行:

'django.middleware.csrf.CsrfViewMiddleware',
vojdkbi0

vojdkbi03#

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

kknvjkwl4#

这里的问题是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/ www.example.com中创建了这个类middle.py,然后在www.example.com的中间件中导入这个中间件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',

]

在django1.11上可以和DRF一起使用

mtb9vblg

mtb9vblg5#

对于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。*
n9vozmp4

n9vozmp46#

这个答案可能不太恰当,但我希望它能帮助你

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

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

pgvzfuti

pgvzfuti7#

如果您想在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之前

niknxzdl

niknxzdl8#

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

我通过以下两个步骤解决了这个问题:
1.将此类添加到utils.py文件:

from django.utils.deprecation import MiddlewareMixin

from <your-project-name> import settings
class DisableCSRF(MiddlewareMixin):
   def process_request(self, request):
      if settings.DEBUG:
         setattr(request, '_dont_enforce_csrf_checks', True)

1.在settings.py文件中,将上述中间件添加到MIDDLEWARE列表中:

...
MIDDLEWARE = [
    ...
    'django.middleware.csrf.CsrfViewMiddleware',
    ...
    '<path-of-utils.py>.utils.DisableCSRF',
]
...
zd287kbt

zd287kbt9#

CSRF可以在视图级别强制执行,不能全局禁用
在某些情况下,这是一个痛苦,但嗯,“这是为了安全”。必须保留那些AAA评级。
https://docs.djangoproject.com/en/dev/ref/csrf/#contrib-and-reusable-apps

相关问题