2016-03-08 13 views
6

Ne ho visto molto su SO, ma nulla può risolvere il mio problema.Django 1.9 AJAX modulo errore CSRF token 403 - "cookie CSRF non impostato"

Problema:

Con CSRF middleware abilitato, Django risponde con 403 su AJAX modulo di richiesta, affermando: "biscotto CSRF non impostata"

Dopo la documentation, una funzionalità di JS è stato implementato, che imposta personalizzati "X-CSRFToken" intestazione.

Esso funziona come previsto, si "csrftoken" cookie dal browser e messaggi insieme con richiesta AJAX:

x-csrftoken: 1a0u7GCQG0wepZHQNThIXeYpMy2lZOf2 

Ma la risposta è ancora 403.

soluzioni provato:

Ho provato tutto quello che ho trovato su SO o sul web, in particolare:

  • controllando che il middleware è abilitato:

    MIDDLEWARE_CLASSES = [ 
        ... 
        'django.middleware.common.CommonMiddleware', 
        'django.middleware.csrf.CsrfViewMiddleware', 
        'django.contrib.auth.middleware.AuthenticationMiddleware', 
        ... 
    ] 
    
  • Browser diversi con i cookie abilitati;

  • Decorare la mia vista con @ensure_csrf_cookie;

  • Impostazione {% csrf_token %} nel modello;

  • Utilizzo del collegamento render che accetta il contesto della richiesta corretta;

  • Impostazione personalizzata CSRF_COOKIE_NAME e CSRF_HEADER_NAME nel mio settings.py;

  • Impostazione esplicita CSRF_COOKIE_SECURE = False e CSRF_COOKIE_HTTPONLY = False;

  • Impostazione esplicita dell'impostazione CSRF_TRUSTED_ORIGINS;

  • Test su server di sviluppo e produzione;

  • Anche a request.META["CSRF_COOKIE_USED"] = True a mio avviso, come qualcuno ha suggerito.

E ancora non ha ottenuto nulla.

intestazioni:

Se uso @csrf_exempt e print(request.META) a mio avviso, è chiaro che intestazione personalizzata "X-CSRFToken" è presente nella richiesta e formattata in base alla documentazione Django, con il prefisso "HTTP_" , ha sostituito i trattini con caratteri di sottolineatura, tutti maiuscoli: "HTTP_X_CSRFTOKEN".

Ancora di più, è una corrispondenza di valori con il set di cookie di Django.

Cookies:

cosa strana è che se provo a print(request.COOKIES) a mio avviso, a pagina e la forma del carico posso vedere "csrftoken" cookie di lì, ma dizionario è vuota su richiesta AJAX . Può essere il problema?

Alla disperata ricerca di ciò che è effettivamente sbagliato. Grazie per aver letto questo.

+0

Puoi mostrare la vostra vista reale e JavaScript? – Alasdair

+0

Che cosa stai utilizzando per inviare una richiesta AJAX? jQuery? – Smile0ff

+0

@ Smile0ff: API di recupero. – Nevertheless

risposta

6

Ok, la questione è molto semplice, allora:

Fetch API non sta inviando le credenziali di default. Secondo MDN:

Le credenziali proprietà di sola lettura dell'interfaccia richiesta indica se l'utente dovrebbe inviare cookie dall'altro dominio nel caso di richieste cross-origine. Questo è simile al simbolo di XHR con flag di Credentials, ma con tre valori disponibili.

Il valore predefinito è omit e non invia mai cookie. Hai solo bisogno di aggiungere ai tuoi same-originfetch() argomenti delle funzioni:

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

E sarete pronti per partire:)