2011-10-19 18 views

risposta

13

È necessario impostare un'intestazione HTTP personalizzata, X-CSRFToken, nella richiesta AJAX. Vedi: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

Se hai già seguito questo consiglio, dovrebbe funzionare. Usa qualcosa come Firebug per monitorare la richiesta che viene inviata e ispeziona le intestazioni per assicurarti che l'intestazione personalizzata venga effettivamente trasmessa. In caso contrario, controlla di nuovo l'implementazione per assicurarti di averlo fatto esattamente come descritto dai documenti.

Si noti inoltre:

A causa di un bug introdotto in jQuery 1.5, l'esempio di cui sopra non funziona correttamente su tale versione. Assicurati di eseguire almeno jQuery 1.5.1.

+0

Grazie per la punta con Firebug. Questo l'ha fatto. Potrebbe vedere il Token nel Cookie e quello nella richiesta. Capito che il problema non era in questa parte della mia app. Per rispondere alla mia domanda: il campo del tag modello non è necessario a causa di questa funzione Pre-AJAX. Destra? –

+1

Sì, e se ho capito bene i documenti, Django sta completamente superando il tag del modello, preferendo i cookie per gestire il token CSRF. –

0

un token CSRF viene assegnato a ogni sessione (vale a dire ogni volta che si accede a). Quindi, prima che tu voglia inserire alcuni dati inseriti dall'utente e inviarli come una chiamata ajax ad una funzione che è protetta da csrf_protect decorator, prova a trovare le funzioni che vengono chiamate prima di ottenere questi dati dall'utente. Per esempio. alcuni modelli devono essere sottoposti a rendering su cui l'utente sta inserendo i dati. Quel modello è reso da alcune funzioni. In questa funzione puoi ottenere il token csrf come segue: csrf = request.COOKIES ['csrftoken'] Ora passa questo valore csrf nel dizionario di contesto su quale modello in questione viene eseguito il rendering. Ora in quel modello scrivi questa riga: Ora nella tua funzione javascript, prima di fare una richiesta jax, scrivi questo: var csrf = $ ('# csrf'). Val() questo sceglierà il valore del token passato al template e lo memorizzerà nella variabile CSRF. Ora mentre effettui una chiamata ajax, nei tuoi dati di post, passa anche questo valore: "csrfmiddlewaretoken": csrf

Questo funzionerà anche se non stai implementando i moduli django.

In effetti, la logica qui è la seguente: è necessario token che è possibile ottenere dalla richiesta. Quindi devi solo capire la funzione che viene chiamata immediatamente dopo il login. Una volta che hai questo token, fai un'altra chiamata ajax per ottenerla o passala ad un template accessibile dal tuo ajax.

0

Ci sono due passaggi nella configurazione del token CSRF, se si desidera pubblicare senza un modulo.

1) Ottieni il csrftoken da Cookie.

2) Una volta ottenuto csrftoken, è necessario impostare l'intestazione con csrftoken (prima di inviare POST i dati).


1) Ottenere il csrftoken da Cookie.

// Function to GET csrftoken from Cookie 
function getCookie(name) { 
    var cookieValue = null; 
    if (document.cookie && document.cookie !== '') { 
     var cookies = document.cookie.split(';'); 
     for (var i = 0; i < cookies.length; i++) { 
      var cookie = jQuery.trim(cookies[i]); 
      // Does this cookie string begin with the name we want? 
      if (cookie.substring(0, name.length + 1) === (name + '=')) { 
       cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 
       break; 
      } 
     } 
    } 
    return cookieValue; 
} 

var csrftoken = getCookie('csrftoken'); 

2) Una volta che avete la csrftoken, è necessario impostare l'intestazione con csrftoken (prima di postare i dati).

function csrfSafeMethod(method) { 
    // these HTTP methods do not require CSRF protection 
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
} 

// Function to set Request Header with `CSRFTOKEN` 
function setRequestHeader(){ 
    $.ajaxSetup({ 
     beforeSend: function(xhr, settings) { 
      if (!csrfSafeMethod(settings.type) && !this.crossDomain) { 
       xhr.setRequestHeader("X-CSRFToken", csrftoken); 
      } 
     } 
    }); 
} 

function postSomeData() { 
    ..... 
    setRequestHeader(); 

    $.ajax({ 
     dataType: 'json', 
     type: 'POST', 
     url: "/url-of-some-api/", 
     data: data, 
     success: function() { 
      alert('success'); 
     }, 
     error: function() { 
      alert('error'); 
     } 
    }); 

}