Wie deaktiviere ich die CSRF-Validierung von Django?

111

Ich habe CSRF-Prozessor- und Middleware-Zeilen in auskommentiert 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 )

Wenn ich jedoch Ajax zum Senden einer Anfrage verwende, antwortet Django immer noch, dass das CSRF-Token falsch ist oder fehlt. Nach dem Hinzufügen von X-CSRFToken zu den Headern ist die Anfrage erfolgreich.

Was geht hier vor sich ?

WoooHaaaa
quelle
Mögliches Duplikat: stackoverflow.com/questions/1650941/…
Rohan

Antworten:

232

Wenn Sie nur einige Ansichten benötigen, um CSRF nicht zu verwenden, können Sie Folgendes verwenden @csrf_exempt:

from django.views.decorators.csrf import csrf_exempt

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

Weitere Beispiele und andere Szenarien finden Sie in der Django-Dokumentation:

Salvatorelab
quelle
2
Hallo, @TheBronx, ich möchte wirklich wissen, warum meine Lösung nicht funktioniert.
WoooHaaaa
1
Entschuldigung @ MrROY Ich weiß nicht, warum Ihre Lösung nicht funktioniert. Ich weiß nur, dass das so @csrf_exempfunktioniert, wie ich es kürzlich ohne Probleme verwendet habe. Hoffe du findest die Antwort.
Salvatorelab
6
@ MrROY, es ist eine Django-Sache. Die meisten Dinge funktionieren / funktionieren nicht, nur weil eine magische Einstellung tief in der Codebasis vergraben ist.
Idursun
2
Zur Erinnerung: Wenn Sie andere Dekorateure in derselben Ansicht haben, ist die Reihenfolge relevant. Platzieren Sie also zuerst @csrf_exempt.
Patrick Bassut
3
Hmm- vielleicht eine technisch korrekte Antwort, aber mit Sicherheit nicht das, was das OP wollte oder wonach ich suchte.
Danny Staple
40

Um CSRF für klassenbasierte Ansichten zu deaktivieren, hat Folgendes für mich funktioniert.
Verwenden von Django 1.10 und 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')
Martijn ten Hoor
quelle
32

In setting.pyMIDDLEWARE können Sie diese Zeile einfach entfernen / kommentieren:

'django.middleware.csrf.CsrfViewMiddleware',
Rohit33
quelle
1
Dies funktioniert für mich auf Django 2.1 mit Curl als http-Client.
Ton
1
@xtrinch Stellen Sie sicher, dass Sie den Serverprozess vollständig beenden / neu starten. Ich glaube nicht, dass das Auto-Relaod die Änderung aufnimmt
Basic
15

Für Django 2 :

from django.utils.deprecation import MiddlewareMixin


class DisableCSRF(MiddlewareMixin):
    def process_request(self, request):
        setattr(request, '_dont_enforce_csrf_checks', True)

Diese Middleware muss gegebenenfalls hinzugefügt settings.MIDDLEWAREwerden (z. B. in Ihren Testeinstellungen).

Hinweis: Die Einstellung wird nicht mehr aufgerufen MIDDLEWARE_CLASSES.

François Constant
quelle
11

Die Antwort mag unangemessen sein, aber ich hoffe, sie hilft Ihnen

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

Eine solche Middleware hilft beim Debuggen von Anforderungen und beim Überprüfen von csrf auf Produktionsservern.

naren
quelle
Hmm. Versuchte dies in Django 1.9.1. Der Dekorator @csrf_exempt wurde aus der Methode entfernt und der obige Code hinzugefügt. Ich habe eine 403 bekommen, weil der Cookie nicht gesetzt wurde.
Craig S. Anderson
11

Das Problem hierbei ist, dass SessionAuthentication eine eigene CSRF-Validierung durchführt. Aus diesem Grund wird der CSRF-Fehler auch dann angezeigt, wenn die CSRF-Middleware kommentiert wird. Sie können jeder Ansicht @csrf_exempt hinzufügen. Wenn Sie jedoch CSRF deaktivieren und die Sitzungsauthentifizierung für die gesamte App durchführen möchten, können Sie eine zusätzliche Middleware wie diese hinzufügen.

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

Ich habe diese Klasse in myapp / middle.py erstellt. Dann importiere diese Middleware in Middleware in 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',

]

Das funktioniert mit DRF auf Django 1.11

Madhuri Gole
quelle
3
Vielen Dank, dass Sie die Frage tatsächlich beantwortet haben, anstatt nur eine Lösung zu veröffentlichen.
Donnerstag,
5

Wenn Sie es in Global deaktivieren möchten, können Sie eine benutzerdefinierte Middleware wie diese schreiben

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)

Fügen Sie diese Klasse dann zuvor youappname.middlewarefilename.DisableCsrfCheckzu MIDDLEWARE_CLASSESListen hinzudjango.middleware.csrf.CsrfViewMiddleware

JJP
quelle
0

@WoooHaaaa Einige Pakete von Drittanbietern verwenden die Middleware 'django.middleware.csrf.CsrfViewMiddleware'. Zum Beispiel benutze ich django-rest-oauth und ich habe ein Problem wie Sie, auch nachdem ich diese Dinge deaktiviert habe. Vielleicht haben diese Pakete wie in meinem Fall auf Ihre Anfrage reagiert, weil Sie den Authentifizierungsdekorator und so etwas verwenden.

M.qaemi Qaemi
quelle