簡體   English   中英

如何禁用 Django 的 CSRF 驗證?

[英]How to disable Django's CSRF validation?

我在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 不正確或丟失”,並且將 X-CSRFToken 添加到 headers 后,請求會成功。

這里發生了什么 ?

如果你只需要一些不使用 CSRF 的視圖,你可以使用@csrf_exempt

from django.views.decorators.csrf import csrf_exempt

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

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

要為基於類的視圖禁用 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')

在 MIDDLEWARE 中的setting.py中,您可以簡單地刪除/注釋此行:

'django.middleware.csrf.CsrfViewMiddleware',

這里的問題是 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

對於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

答案可能不恰當,但希望對您有所幫助

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

擁有這樣的中間件有助於調試請求並檢查生產服務器中的 csrf。

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

CSRF 可以在視圖級別強制執行,不能全局禁用

在某些情況下,這是一種痛苦,但嗯,“這是為了安全”。 必須保留那些AAA評級。

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

@WoooHaaaa 一些第三方軟件包使用“django.middleware.csrf.CsrfViewMiddleware”中間件。 例如,我使用 django-rest-oauth 並且即使在禁用這些東西后我也有像你一樣的問題。 也許這些包像我的情況一樣響應了您的請求,因為您使用了身份驗證裝飾器之類的東西。

在使用此解決方案之前,請閱讀文檔中的此鏈接


我通過以下兩個步驟解決了這個問題:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM