2013-05-17 4 views
13

ich den django Rest Rahmen bin mit API-Aufrufen über IOS auszuführen und ich erhalte die folgenden Fehler "CSRF fehlgeschlagen:. CSRF Cookie nicht gesetzt"Django REST-Framework CSRF fehlgeschlagen: CSRF Cookie nicht

Hier ist meine 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 tun?

+0

Haben Sie das jemals herausgefunden? Ich bin nie darüber hinweggekommen. – user798719

+0

Mögliches Duplikat von [Django Rest Framework entfernen csrf] (http://stackoverflow.com/questions/30871033/django-rest-framework-remove-csrf) – user3467349

Antwort

1

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

Wenn Sie Daten mit einem POST ändern, sollten Sie eine CSRF haben, wenn Sie eine sitzungsbasierte Authentifizierung verwenden. Andernfalls öffnest du ein Sicherheitsloch. Auch wenn Sie glauben, dass Ihr Django-Server iPhone-Apps bedienen wird, gibt es nichts, was Sie davon abhalten könnte, die Pakete auf Ihrem Server zu schnüffeln und dann den Engineering-Zugriff auf den Server mit anderen Arten von Web-Clients rückgängig zu machen. Aus diesem Grund benötigt Django Rest Framework in einigen Fällen eine CSRF. Dies wird in der erwähnt.

Der Pfad 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 übergeben werden.

+0

> unsere app von schnüffeln die Pakete auf den Verkehr - https, also nein Das ist nicht der Grund. – user3467349

+0

Wenn Sie das Risiko haben, CSRF zu deaktivieren, weil Sie nicht der Meinung sind, dass Ihre Pakete unsicher sind und kein Browser beteiligt ist, sollten Sie die Lösung von @Rahul Gupta-Iwasaki ausprobieren –

11

Wenn noch jemand diese Frage befolgt, ist die direkte Antwort, dass Sie den Decorator für die View-Methode selbst verwenden müssen. Die Methoden get und post, die in der Klasse definiert sind, teilen DRF mit, wie sich die tatsächliche Ansicht verhalten soll. Die vom django Router erwartete Ansichtsmethode wird jedoch erst beim Aufruf von LoginView.as_view() instanziiert.

Die Lösung besteht darin, den csrf_exempt Dekorierer zu urls.py hinzuzufügen. Es könnte wie folgt 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())), 
    ... 
) 

Doch wie Mark oben weisen darauf hin, csrf Schutz ist wichtig, um Ihre Sitzungen zu verhindern, entführt zu werden. Ich habe selbst nicht mit iOS gearbeitet, aber ich würde gerne djangos cookie-based csrf tokens verwenden. Sie können den ensure_csrf_cookie Decorator verwenden, um django dazu zu veranlassen, einen csrftoken Cookie mit einer Antwort zu senden, und Ihre POST Anfragen werden validiert, solange Sie diesen Token als X-CSRFToken Header einschließen.

0

Dies ist eine alte Frage, aber etwas, auf das wir kürzlich gestoßen sind.

DRF deaktiviert CSRF standardmäßig, sofern keine Sitzungsauthentifizierung verwendet wird. Standardmäßig ist NSURLconnection eingerichtet, um mit Cookies umzugehen. Sie müssen der iOS-App ausdrücklich mitteilen, keine Cookies zu verwenden. Dann können Sie bei Bedarf weiterhin die Session-Authentifizierung verwenden und Ihre Ansichten nicht von csrf befreien.

1

Das Problem, das Sie hier finden, ist, dass Django für die Verarbeitung Ihrer Ansicht verwendet, was immer as_view() Methode zurückgibt, nicht direkt Methode get() oder post().

Daher sollten Sie Ihre klassenbasierte Ansicht in einer der folgenden Weisen schmücken:

  1. In Urls.py
 
    urlpatterns = patterns('', 
     url('^login/$', csrf_exempt(views.LoginView.as_view())), 
     ... 
    ) 
  1. oder dispatch() Verfahren (pre django 1,9)
 
    from django.utils.decorators import method_decorator 

    class LoginView(APIView): 
     @method_decorator(csrf_exempt) 
     def dispatch(self, *args, **kwargs): 
      ... 
  1. oder Klassenansicht selbst (von django 1,9)
 
    from django.utils.decorators import method_decorator 


    @method_decorator(csrf_exempt, name='dispatch') 
    class LoginView(APIView): 
      ... 
0

Ich hatte das gleiche Problem. Mein Problem war, dass ich aber .as_view() in urls.py auf MyAPIView vergesse. So muss es sein wie:

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

nicht:

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