2016-08-31 2 views
0

Ich benutze mit Hilfe von Django Rest Framework Browsable API mit ModelViewSet CRUD-Aktionen zu tun und wollen permissions.IsAuthenticatedOrReadOnly, aber wenn ich geloggt bin und versuche zu löschen oder PUT ich "detail": "CSRF Failed: CSRF token missing or incorrect.""CSRF-Token fehlt" mit PUT/DELETE Meathod Rest-Framework

Meine Ansicht wie folgt aussieht

class objViewSet(viewsets.ModelViewSet): 
    queryset = obj.objects.all() 
    serializer_class = objSerializer 
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,) 

Settings.py

REST_FRAMEWORK = { 
'DEFAULT_PERMISSION_CLASSES': (
    'rest_framework.permissions.AllowAny', 
), 

Serializer i Obwohl s nur

class ObjSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Obj 

wenn ich permission_classes löschen (so die Standard-allowAny auslöst) Ich kann es ganz gut funktioniert.

Was ich will

der Lage sein, nur PUT/DELETE, wenn ich authentifiziert bin. Ich weiß nicht, wie CSRF-Token zu senden, wenn alles automatisch passiert (Modalviewset funktioniert die ganze Arbeit)

+0

Sie möchten csrf Checks global entfernen? oder separate nicht csrf Ansichten? – itzMEonTV

+0

Für den Fall, dass Sie keine bessere Lösung hier finden, gehört mir: Ich wette, Sie verwenden 'rest_framework.authentication.SessionAuthentication' als eine der Authentifizierungsklassen. Entfernen Sie es aus den Einstellungen und alles sollte korrekt funktionieren. –

Antwort

0

In Ihren REST_FRAMEWORK Einstellungen, die Sie nicht das Authentifizierungsschema erwähnt haben so DRF das Standardauthentifizierungsschema verwendet, das SessionAuthentication ist. Dieses Schema macht es zwingend erforderlich, dass Sie das csrf-Token mit Ihren Anfragen versehen. Sie können dies überwinden, indem sie:

  1. Um diese Einstellung für das gesamte Projekt in settings.py


    REST_FRAMEWORK = { 
     'DEFAULT_AUTHENTICATION_CLASSES': (
      'rest_framework.authentication.BasicAuthentication', 
     )} 

hinzufügen zu machen
  1. Um diese Einstellung in bestimmten Ansicht zu machen gehen Sie wie folgt aus Ihrer Sicht


    class objViewSet(viewsets.ModelViewSet): 
     queryset = obj.objects.all() 
     serializer_class = objSerializer 
     permission_classes = (permissions.IsAuthenticatedOrReadOnly,) 
     authentication_classes = (BasicAuthentication,) 

Quelle: http://www.django-rest-framework.org/api-guide/authentication/#sessionauthentication

BTW, csrf-Token wird als Cookie namens 'csrftoken' gespeichert.Sie können es aus der HTTP-Antwort abrufen und es mit dem Schlüssel 'X-CSRFToken' an Ihre Anforderungsheader anhängen. Sie können einige Details davon sehen: https://docs.djangoproject.com/en/dev/ref/csrf/#ajax

-1

Sie können CSRF-Check auf einzelne URLs entfernen. Versuchen Sie, diese auf Ihrem urls.py:

url(r'^/my_url_to_view/', csrf_exempt(views.my_view_function), name='my_name'), 
0

Sie haben SessionAuthentication und Sitzungs Auth Kontrollen könnten verwendet für die csrf_token immer und Sie können die Kontrollen zu vermeiden, indem Freistellung aber Lässt das nicht tun.

Ich denke, Sie können beide Authentifizierungsklassen beibehalten. oder nur TokenAuthentication. dh

'DEFAULT_AUTHENTICATION_CLASSES': (
    # 'rest_framework.authentication.BasicAuthentication', 
    'rest_framework.authentication.TokenAuthentication', 
    'rest_framework.authentication.SessionAuthentication', 

    # 'oauth2_provider.ext.rest_framework.OAuth2Authentication', 
    # 'rest_framework_social_oauth2.authentication.SocialAuthentication', 
), 

Und wenn Sie nicht für TokenAuth und nur die Sitzung Auth gehen. Sie können csrf_token immer über den X-CSRFToken-Header übergeben. Oder Sie können einfach für csrf_except Dinge gehen. wodurch die csrf-Probleme vermieden werden.

Dies sollte funktionieren. Siehe auch die folgenden Links.

ref: https://stackoverflow.com/a/26639895/3520792

ref: https://stackoverflow.com/a/30875830/3520792

+0

"Sie können immer csrf_token über X-CSRFToken-Header übergeben" das ist genau das, was ich nicht weiß, wie zu tun, weil ich ModelSetView –

+0

verwende Es geht nicht darum, welche Ansicht Sie verwenden. Sie verwenden eine Sitzung und der Server erhält csrf_token nicht von der Client-Seite. Sie übergeben csrf_token einfach im X-CSRFToken-Anforderungsheader. Es gibt Möglichkeiten, das csrf_token auf der Clientseite zu erhalten. ref: - http://stackoverflow.com/questions/22063612/adding-csrftoken-to-ajax-request, http://stackoverflow.com/questions/28417781/jquery-add-csrf-toke-to-all- post-requests-data Ermittle es einfach. Es ist nur Ihre Anfrage Header sollte es haben. –

+0

Ich bekomme es von Client-Seite mit Ajax zu tun. Aber meine Client-Seite (browsable api) wird automatisch von django generiert, was bedeutet - ich habe keinen Zugriff darauf. Gibt es eine Möglichkeit, meine Ansichten (so dass sie CSRFToken enthalten) im Django-Code zu ändern oder muss ich diese brovsable API-Ansicht überschreiben und dann Ajax verwenden, wenn ich auf "PUT"/"DELETE" klicke? –

Verwandte Themen