2016-03-08 8 views
6

Ich habe eine Menge darüber auf SO gesehen, aber nichts kann mein Problem beheben.Django 1.9 AJAX Formular CSRF Token 403 Fehler - "CSRF-Cookie nicht gesetzt"

Problem:

Mit CSRF-Middleware aktiviert ist, antwortet Django mit 403 auf AJAX Formular Anfrage, die besagt: "CSRF Cookie nicht"

Nach dem documentation wurde eine JS-Funktionalität implementiert, das Header benutzerdefinierte "X-CSRFToken" setzt.

Es funktioniert wie erwartet, bekommt "csrftoken" Cookie von Browser und trägt ihn zusammen mit AJAX Anfrage:

x-csrftoken: 1a0u7GCQG0wepZHQNThIXeYpMy2lZOf2 

Aber Antwort ist noch 403.

Versuchte Lösungen:

ich habe alles versucht, ich auf SO oder Web finden konnte, und zwar:

  • Überprüfung, dass Middleware aktiviert ist:

    MIDDLEWARE_CLASSES = [ 
        ... 
        'django.middleware.common.CommonMiddleware', 
        'django.middleware.csrf.CsrfViewMiddleware', 
        'django.contrib.auth.middleware.AuthenticationMiddleware', 
        ... 
    ] 
    
  • Verschiedene Browser mit Cookies aktiviert;

  • meiner Ansicht nach mit @ensure_csrf_cookie Dekorieren;

  • Einstellung {% csrf_token %} in meiner Vorlage;

  • Mit render Verknüpfung des richtigen Anforderungskontext stattfindet;

  • Einstellen von benutzerdefinierten CSRF_COOKIE_NAME und CSRF_HEADER_NAME in meinem settings.py;

  • Explizit Einstellung CSRF_COOKIE_SECURE = False und CSRF_COOKIE_HTTPONLY = False;

  • Explizit CSRF_TRUSTED_ORIGINS Einstellung Einstellung;

  • Testen auf Entwicklungs- und Produktionsservern;

  • Auch request.META["CSRF_COOKIE_USED"] = True meiner Ansicht nach als jemand vorgeschlagen.

Und immer noch nichts.

Headers:

Wenn ich @csrf_exempt und print(request.META) meiner Meinung nach zu verwenden, ist es klar, dass benutzerdefinierte Header "X-CSRFToken" in Anforderung und formatiert nach Django Dokumentation, mit "HTTP_" prefix , ersetzte Bindestriche durch Unterstriche, alle in Großbuchstaben: "HTTP_X_CSRFTOKEN".

Noch mehr, es ist Wert entspricht mit Cookie-Set von Django.

Cookies:

Merkwürdige ist, wenn ich zu print(request.COOKIES) meiner Meinung nach versuchen, auf Seite und Formularlade ich dort „csrftoken“ Cookie sehen kann, aber Wörterbuch ist leer auf AJAX Anfrage . Kann es das Problem sein?

Verzweifelt zu finden, was eigentlich falsch ist. Danke für das Lesen.

+0

Können Sie Ihre aktuelle Ansicht und Javascript zeigen? – Alasdair

+0

Was verwenden Sie, um eine AJAX-Anfrage zu senden? jQuery? – Smile0ff

+0

@ Smile0ff: Fetch API. – Nevertheless

Antwort

6

Ok, ist die Frage ganz einfach dann:

Fetch API ist nicht Anmeldeinformationen standardmäßig sendet. Nach MDN:

Die Anmeldeinformationen schreibgeschützte Eigenschaft der Request-Schnittstelle zeigt , ob die User-Agent Cookies von der anderen Domäne in den Fall von Cross-Origin-Anfragen senden soll. Dies ist ähnlich dem XHR withCredentials Flag, aber mit drei verfügbaren Werten.

Standard ist omit, und es sendet nie Cookies. Sie müssen nur same-origin auf Ihre fetch() Funktion Argumente hinzuzufügen:

fetch(formUrl, { 
    ... 
    credentials: 'same-origin', 
    ... 
}) 

und Sie werden gut zu gehen:)