it-swarm.com.de

Django REST Framework CSRF Failed: CSRF-Cookie nicht gesetzt

Ich verwende das Django Rest Framework, um API-Aufrufe über IOS auszuführen, und es wird die folgende Fehlermeldung angezeigt: "CSRF-Fehler: CSRF-Cookie nicht gesetzt."

Hier ist mein Django-API-Code:

class LoginView(APIView):
    """
    List all snippets, or create a new snippet.
    """
    @csrf_exempt
    def get(self, request, format=None):
        startups = Startup.objects.all()
        serializer = StartupSerializer(startups, many=True)
        return Response(serializer.data)

    @csrf_exempt
    def post(self, request, format=None):
        profile = request.POST
....

Was kann ich machen?

17
user2237822

Wenn noch jemand dieser Frage folgt, ist die direkte Antwort, dass Sie den Dekorator für die Ansichtsmethode selbst verwenden müssen. Die Methoden get und post, die in der Klasse APIView definiert sind, teilen DRF lediglich mit, wie sich die tatsächliche Ansicht verhalten soll. Die vom Django-Router erwartete Ansichtsmethode wird jedoch erst dann instanziiert, wenn Sie LoginView.as_view() aufrufen.

Daher besteht die Lösung darin, den Dekorator csrf_exempt zu urls.py hinzuzufügen. Es könnte so aussehen:

#file: urls.py

from Django.conf.urls import patterns, url
from Django.views.decorators.csrf import csrf_exempt

import views

urlpatterns = patterns('',
    url('^login/$', csrf_exempt(views.LoginView.as_view())),
    ...
)

Wie Mark bereits ausgeführt hat, ist der CSRF-Schutz jedoch wichtig, um zu verhindern, dass Ihre Sitzungen missbraucht werden. Ich habe selbst nicht mit iOS gearbeitet, aber ich würde versuchen, Djangos Cookie-basierte CSRF-Token zu verwenden. Sie können den ensure_csrf_cookie-Dekorator verwenden, um Django zu veranlassen, ein csrftoken-Cookie mit einer Antwort zu senden, und Ihre POST-Anforderungen werden validiert, solange Sie dieses Token als X-CSRFToken-Header einfügen.

14

Das Problem, auf das Sie hier stoßen, ist, dass Django für die Verarbeitung Ihrer Ansicht die as_view() -Methode verwendet, die zurückgegeben wird, nicht direkt die get() -Methode oder die post() -Methode.

Daher sollten Sie Ihre klassenbasierte Ansicht auf eine der folgenden Arten dekorieren:

  1. In urls.py
 urlpatterns = patterns ('', 
 url ('^ login/$', csrf_exempt (views.LoginView.as_view ())), 
 ... 
) 
  1. oder auf dispatch() Methode (vor Django 1.9)
 von Django.utils.decorators importieren method_decorator 
 
 Klasse LoginView (APIView): 
 @ method_decorator (csrf_exempt) 
 def dispatch (self, * Argumente, ** kwargs): 
 ... 
  1. oder in der Klassenansicht selbst (ab Django 1.9)
 von Django.utils.decorators importieren method_decorator 
 
 
 @ method_decorator (csrf_exempt, name = 'dispatch') 
 Klasse LoginView (APIView): 
 ... 
3
thedk

Bei GETs sollten Sie keine Daten ändern, sodass kein CSRF erforderlich ist.

Wenn Sie Daten mit einem POST ändern, SOLLTEN Sie eine CSRF haben, wenn Sie die sitzungsbasierte Authentifizierung verwenden. Andernfalls öffnen Sie eine Sicherheitslücke. Auch wenn Sie glauben, dass Ihr Django-Server iPhone-Apps warten wird, gibt es nichts, was jemanden mit Ihrer App davon abhält, die Datenpakete auf Ihrem Server zu riechen und dann den Zugriff auf den Server mit anderen Arten von Web-Clients zurückzugreifen. Aus diesem Grund benötigt Django Rest Framework in einigen Fällen eine CSRF. Dies wird in der Django Rest Framework Dokumentation erwähnt.

Der Weg um diese Anforderung für POSTs besteht darin, keine Sitzungsauthentifizierung zu verwenden. Beispielsweise könnten Sie BasicAuthentication über HTTPS verwenden. Bei diesem Authentifizierungsmechanismus sollten Sie HTTPS verwenden, um zu verhindern, dass Anmeldeinformationen bei jeder Anforderung im Klartext übergeben werden.

2
Mark Chackerian

Ich hatte das gleiche Problem. Mein Problem war, dass ich vergessen habe, .as_view() in urls.py auf MyAPIView zu setzen. So muss es sein:

url(r'$', GetLikesAPI.as_view(), name='list')

nicht:

url(r'$', GetLikesAPI, name='list')
2
М.Б.

In meinem Fall passierte es, weil ich put request an url = ' http://example.com/list/5 ' gesendet habe, ohne am Ende einen Schrägstrich zu setzen. Als ich die URL auf url = ' http://example.com/list/5/ ' änderte, fing alles an zu funktionieren.

1
Radren

Dies ist eine alte Frage, auf die wir in letzter Zeit gestoßen sind.

DRF deaktiviert CSRF standardmäßig, sofern keine Sitzungsauthentifizierung verwendet wird. Standardmäßig ist NSURLconnection für die Behandlung von Cookies eingerichtet. Sie müssen die iOS-App ausdrücklich anweisen, keine Cookies zu verwenden. Dann können Sie bei Bedarf weiterhin die Sitzungsauthentifizierung verwenden und müssen Ihre Ansichten nicht durch csrf ausschließen.

0
kevswanberg
urlpatterns = patterns('',
       url('^login/$', csrf_exempt(views.LoginView.as_view())),
       ...
)

Jungs. Ich hatte den gleichen Fehler und verbrachte viel Zeit damit, dies herauszufinden: 1) Ich hatte einen anderen Router mit 'Login' und dort habe ich '$' verpasst. Ich meine, manchmal kann man beim Routing etwas vergessen und diesen Fehler bekommen.

0
Df.fpm