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を追加した後、リクエストは成功します。

ここで何が起こっているのですか?


回答:


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 2013年

1
申し訳ありませんが@MrROYソリューションが機能しない理由がわかりません。私@csrf_exempは最近それを問題なく使用したのでそれが機能することを知っています あなたが答えを見つけてくれることを願っています。
Salvatorelab 2013年

6
@MrROY、それはDjangoのものです。コードベースの奥深くに魔法の設定が埋め込まれているからといって、ほとんどのことが機能します/機能しません。
idursun 2013

2
注意:同じビューに他のデコレータがある場合、順序は適切です。@ csrf_exemptを最初に配置します。
Patrick Bassut 2013

3
うーん、技術的に正しい答えかもしれませんが、OPが望んでいたものや私が探していたものはおそらく間違いです。
ダニーステープル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
これは、Django 2.1では、curlをhttpクライアントとして使用して動作します。
クレイ

1
@xtrinchサーバープロセスを完全に終了/再起動してください。自動リリースが変更を反映するとは思わない
基本的な

15

以下のためのジャンゴ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を取得しました。
クレイグS.アンダーソン

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に作成し、このミドルウェアをミドルウェアの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を使用していますが、それらを無効にしても問題が発生します。認証デコレータなどを使用しているため、これらのパッケージが私のケースのようにリクエストに応答した可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.