Ich weiß, dass es Antworten zum Django Rest Framework gibt, aber ich konnte keine Lösung für mein Problem finden.
Ich habe eine Anwendung, die Authentifizierung und einige Funktionen hat. Ich habe eine neue App hinzugefügt, die das Django Rest Framework verwendet. Ich möchte die Bibliothek nur in dieser App verwenden. Außerdem möchte ich eine POST-Anfrage stellen und erhalte immer folgende Antwort:
{
"detail": "CSRF Failed: CSRF token missing or incorrect."
}
Ich habe folgenden Code:
# urls.py
from django.conf.urls import patterns, url
urlpatterns = patterns(
'api.views',
url(r'^object/$', views.Object.as_view()),
)
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from django.views.decorators.csrf import csrf_exempt
class Object(APIView):
@csrf_exempt
def post(self, request, format=None):
return Response({'received data': request.data})
Ich möchte die API hinzufügen, ohne die aktuelle Anwendung zu beeinflussen. Meine Frage ist also, wie ich CSRF nur für diese App deaktivieren kann.
django
django-rest-framework
csrf
django-csrf
Irene Texas
quelle
quelle
Antworten:
Warum tritt dieser Fehler auf?
Dies geschieht aufgrund des
SessionAuthentication
von DRF verwendeten Standardschemas . DRFsSessionAuthentication
verwenden das Sitzungsframework von Django zur Authentifizierung, bei dem CSRF überprüft werden muss.Wenn Sie
authentication_classes
in Ihrer Ansicht / Ihrem Ansichtssatz keine definieren , verwendet DRF diese Authentifizierungsklassen als Standard.Da DRF sowohl die sitzungsbasierte als auch die nicht sitzungsbasierte Authentifizierung für dieselben Ansichten unterstützen muss, wird die CSRF-Prüfung nur für authentifizierte Benutzer erzwungen. Dies bedeutet, dass nur authentifizierte Anforderungen CSRF-Token erfordern und anonyme Anforderungen ohne CSRF-Token gesendet werden können.
Wenn Sie eine AJAX-API mit SessionAuthentication verwenden, müssen Sie ein gültiges CSRF-Token für alle "unsicheren" HTTP-Methodenaufrufe, z. B.
PUT, PATCH, POST or DELETE
Anforderungen , einschließen .Was ist dann zu tun?
Um die CSRF-Prüfung zu deaktivieren, können Sie jetzt eine benutzerdefinierte Authentifizierungsklasse erstellen,
CsrfExemptSessionAuthentication
die von der Standardklasse abweichtSessionAuthentication
. In dieser Authentifizierungsklasse überschreiben wir dieenforce_csrf()
Prüfung, die innerhalb der tatsächlichen durchgeführt wurdeSessionAuthentication
.In Ihrer Ansicht können Sie dann Folgendes definieren
authentication_classes
:Dies sollte den csrf-Fehler behandeln.
quelle
Einfachere Lösung:
Verwenden Sie in views.py die geschweiften Klammern CsrfExemptMixin und authentication_classes:
quelle
Ändern Sie urls.py
Wenn Sie Ihre Routen in urls.py verwalten, können Sie Ihre gewünschten Routen mit csrf_exempt () umschließen, um sie von der CSRF-Überprüfungs-Middleware auszuschließen.
Alternativ als Dekorateur Einige finden die Verwendung des Dekorators @csrf_exempt möglicherweise besser für ihre Bedürfnisse geeignet
zum Beispiel,
sollte den Job erledigt bekommen!
quelle
Für alle, die keine hilfreiche Antwort gefunden haben. Ja, DRF entfernt automatisch den CSRF-Schutz, wenn Sie die
SessionAuthentication
AUTHENTICATION CLASS nicht verwenden. Beispielsweise verwenden viele Entwickler nur JWT:Das Problem
CSRF not set
kann jedoch auch aus einem anderen Grund auftreten. Beispielsweise haben Sie Ihrer Ansicht den Pfad nicht korrekt hinzugefügt:anstatt
quelle
Ich habe einige der obigen Antworten ausprobiert und fand, dass das Erstellen einer separaten Klasse etwas über Bord ging.
Als Referenz stieß ich auf dieses Problem, als ich versuchte, eine funktionsbasierte Ansichtsmethode auf eine klassenbasierte Ansichtsmethode für die Benutzerregistrierung zu aktualisieren.
Wenn Sie klassenbasierte Ansichten (CBVs) und Django Rest Framework (DRF) verwenden, erben Sie von der ApiView-Klasse und setzen Sie Berechtigungsklassen und Authentifizierungsklassen auf ein leeres Tupel. Unten finden Sie ein Beispiel.
quelle
Wenn Sie die sitzungsbasierte Authentifizierung nicht verwenden möchten, können Sie sie
Session Authentication
aus REST_AUTHENTICATION_CLASSES entfernen. Dadurch werden automatisch alle csrf-basierten Probleme entfernt. In diesem Fall funktioniert Browseable apis möglicherweise nicht.Außerdem sollte dieser Fehler auch bei der Sitzungsauthentifizierung nicht auftreten. Sie sollten benutzerdefinierte Authentifizierung wie TokenAuthentication für Ihre APIs verwenden und stellen Sie sicher , zu senden
Accept:application/json
undContent-Type:application/json
(vorausgesetzt , Sie verwenden json) in Ihre Anfragen zusammen mit Authentifizierungs - Token.quelle
Sie müssen dies hinzufügen, um die Standard-Sitzungsauthentifizierung zu verhindern: (settings.py)
Dann: (views.py)
quelle
Ich bin mit dem gleichen Problem konfrontiert. Ich folgte dieser Referenz und es funktionierte. Die Lösung besteht darin, eine Middleware zu erstellen
Fügen Sie die Datei disable.py in eine Ihrer Apps ein (in meinem Fall ist es 'myapp').
Und fügen Sie die Mittelware zu den MIDDLEWARE_CLASSES hinzu
quelle
Wenn Sie eine exklusive virtuelle Umgebung für Ihre Anwendung verwenden, können Sie den folgenden Ansatz verwenden, ohne andere Anwendungen zu aktivieren.
Was Sie beobachtet geschieht , weil
rest_framework/authentication.py
diesen Code in das hatauthenticate
Methode derSessionAuthentication
Klasse:Sie können die
Request
Klasse so ändern , dass eine Eigenschaft aufgerufen wird,csrf_exempt
und sie in Ihrer jeweiligen View-Klasse initialisieren,True
wenn Sie keine CSRF-Prüfungen wünschen. Beispielsweise:Ändern Sie als Nächstes den obigen Code wie folgt:
Es gibt einige verwandte Änderungen, die Sie in der
Request
Klasse vornehmen müssten . Eine vollständige Implementierung finden Sie hier (mit vollständiger Beschreibung): https://github.com/piaxis/django-rest-framework/commit/1bdb872bac5345202e2f58728d0e7fad70dfd7edquelle
Meine Lösung wird Schlag gezeigt. Dekoriere einfach meine Klasse.
quelle
Bei Verwendung von REST-API-POSTs kann das Fehlen eines X-CSRFToken-Anforderungsheaders diesen Fehler verursachen. Django-Dokumente enthalten einen Beispielcode zum Abrufen und Festlegen des CSRF-Tokenwerts von JS.
Wie in den obigen Antworten angegeben, erfolgt die CSRF-Prüfung, wenn die SessionAuthentication verwendet wird. Ein anderer Ansatz ist die Verwendung von TokenAuthentication. Beachten Sie jedoch, dass TokenAuthentication an erster Stelle in der Liste der DEFAULT_AUTHENTICATION_CLASSES der Einstellung REST_FRAMEWORK stehen sollte.
quelle
Dies kann auch während eines DNS-Rebinding-Angriffs ein Problem sein .
Zwischen DNS-Änderungen kann dies auch ein Faktor sein. Wenn Sie warten, bis DNS vollständig gelöscht ist, wird dies behoben, wenn es vor DNS-Problemen / -Änderungen funktioniert hat.
quelle