Django Rest Framework, AJAX-POST funktioniert, aber PATCH löst CSRF aus Fehlgeschlagen: CSRF-Token fehlt oder ist falsch

8

Ich portiere mein Projekt nach Django Rest Framework , um eine richtige REST API für mein Projekt zu erstellen. Ich denke, es hilft viel beim Entwurf der API und macht sie robust, aber ich stoße auf ein Problem:

Ich habe ein Einstiegsmodell und zugehörige ListCreateAPIView und RetrieveUpdateDestroyAPIView Ansichten. Ich kann eine neue Eintragsinstanz erfolgreich in der Liste durch eine Ajax-Anfrage veröffentlichen und die csrfmiddlewaretoken wie in der regulären Django-Ansicht bereitstellen.

%Vor%

Nun versuche ich, einen Patch auf eine existierende Instanz anzuwenden, indem ich dieselbe csrfmiddlewaretoken like so verwende:

%Vor%

Der Antwortstatuscode ist dann 403 FORBIDDEN vith error CSRF Failed: CSRF token missing or incorrect , obwohl ich in firebux eingecheckt habe, dass csrfmiddlewaretoken in den Anfragedaten ist.

Ich weiß nicht, was falsch ist und ich kann nicht herausfinden, wo im Code die Anfrage abgelehnt wurde.

Hinweis: Ich kann das Objekt mit der Django Rest Framework durchsuchbaren API patchen.

Ich hoffe, dass jemand helfen kann. Vielen Dank. Olivier

BEARBEITEN

Ich habe in den Code geforscht, um zu sehen, wo die Anforderung der PATCH-Anforderung auftritt, und ich habe in django.middleware.csrt.py Folgendes gefunden:

%Vor%

Der zweite Test schlägt fehl, da es sich nicht um eine POST-Anforderung handelt, sondern die erforderlichen Informationen in request.DATA enthalten sind. Es scheint also, dass Django keine PATCH-Anfrage akzeptiert. Was denkst du wäre der beste Weg, dies zu umgehen?

Würden Sie ein anderes Authentifizierungssystem empfehlen (es gibt einige in der Django-Rest-Framework-Dokumentation)?

EDIT2

Ich habe eine Lösung gefunden: Ich habe beobachtet, dass das durchsuchbare API tatsächlich eine POST-Anfrage sendet, aber mit einem Parameter _method="PATCH", also habe ich dasselbe mit meiner Ajax-Anfrage gemacht und es funktioniert gut.

Ich weiß nicht, ob es der richtige Weg ist, jede Rückmeldung und Meinung ist willkommen!

EDIT3

Nach mehr Lektüre entdeckte ich (ich wusste schon irgendwie ...), dass einige Browser keine Anfragen wie PUT, PATCH, DELETE unterstützen, sondern eine Post-Anfrage mit X-HTTP- senden. Method-Override in der Kopfzeile.

Ich denke also, der gute Weg ist, folgendes zu tun:

%Vor%     
overlii 02.04.2014, 13:28
quelle

2 Antworten

6

Ich füge das endlich als Antwort hinzu.

Nach mehr Lektüre entdeckte ich (ich wusste schon irgendwie ...), dass einige Browser keine Anfragen wie PUT, PATCH, DELETE unterstützen, sondern eine Post-Anfrage mit X-HTTP- senden. Method-Override in der Kopfzeile.

Ich denke also, der gute Weg ist, folgendes zu tun:

%Vor%     
overlii 02.01.2015, 17:34
quelle
0

Dies ist keine direkte Lösung für Ihr Problem, aber dies sollte einen gewissen Kontext bereitstellen und eine mögliche Lösung bieten.

Django unterstützt die HTTP-PATCH-Methode nicht und verwirft alle Daten einschließlich des CSRF-Tokens. Eine mögliche Problemumgehung besteht darin, die Methode zu POST zu ändern, Django zu erzwingen, die Anforderung erneut zu verarbeiten, und die Methode erneut zu ändern. Das ist ein bisschen dreckig, aber funktioniert, Beispielcode, wie er von Django Piston verwendet wird hier bereitgestellt:

%Vor%

Ich habe diesen Fix (mit einigen Modifikationen) erfolgreich verwendet und obwohl es sich ein wenig schmutzig anfühlt, scheint es eine sehr brauchbare Lösung zu sein.

Alternativ können Sie die do-Methode in den POST-Daten überladen. Wieder nicht die schönste Lösung, aber sehr praktikabel.

Ich würde gerne jemanden für eine bessere Lösung vorschlagen.

    
Laurens Bosscher 29.09.2014 13:55
quelle