2011-09-26 10 views
34

questo funziona, ma viene fermato perché manca un token di autenticità:Modo corretto per inviare un token di autenticità con AJAX ..?

$(".ajax-referral").click(function(){ 
    $.ajax({type: "POST", url: $(this).parent("form").attr("action"), dataType: "script"}); 
    return false; 
}); 

Così ho provato ad aggiungere in questo modo:

$(".ajax-referral").click(function(){ 
    $.ajax({type: "POST", url: $(this).parent("form").attr("action") + "?&authenticity_token=" + AUTH_TOKEN, dataType: "script"}); 
    return false; 
}); 

E passa l'auth_token correttamente come param, ma sembra perdere il resto della mia forma.

Ad ogni modo è possibile inviare sia i dati del modulo che funzionano, sia il token di autenticità?

Questo è un ambiente rotaie. E ho questo nella mia testa.

= javascript_tag "var AUTH_TOKEN = '#{form_authenticity_token}';" if protect_against_forgery? 

Le cose che ho provato

1.

= hidden_field :authenticity_token, :value => form_authenticity_token 

2.

$.ajax({type: "POST", url: $(this).parent("form").attr("action"), dataType: "script", authenticity_token: AUTH_TOKEN}); 

3.

// Always send the authenticity_token with ajax 
$(document).ajaxSend(function(event, request, settings) { 
    if (settings.type != 'GET') { 
     settings.data = (settings.data ? settings.data + "&" : "") 
      + "authenticity_token=" + encodeURIComponent(AUTH_TOKEN); 
    } 
}); 

risposta

29

In realtà, si sta leggendo l'attributo action della forma e l'invio di una richiesta POST Ajax ad esso. per inviare dati del modulo è necessario inviare il modulo oppure è possibile serializzare i dati del modulo e inviarlo a richiesta AJAX come

$(".ajax-referral").click(function(){ 
    $.ajax({ 
     type: "POST", 
     url: $(this).parent("form").attr("action") + "?&authenticity_token=" + AUTH_TOKEN, 
     data:$(this).parent("form").serialize(), 
     dataType: "script" 
     }); 
    return false; 
}); 

Facendo questo si serializzare i dati del modulo e inviarlo insieme alla richiesta AJAX e il token di autenticità è già inviato tramite stringa di query

+6

Ho dovuto usare encodeURIComponent (AUTH_TOKEN), ma usandolo nella stringa di query ha funzionato una volta fatto. – Ken

+0

il token non deve essere inviato nell'URL! – Gacci

3

È possibile includere AUTH_TOKEN nel modulo stesso come input nascosto.

<input type="hidden" name="AUTH_TOKEN">1234abcd</input> 
+1

No, scusa, questo non funziona. – Trip

+0

'' (Si noti che sto usando JSX per sostituire il '{' con qualsiasi cosa sia appropriata per la lingua del modello. –

+0

funzionerebbe se il nome fosse 'authenticity_token' – WickyNilliams

14

Grazie!

Giusto per chiarire per l'uso più comune.

Hai bisogno del tag js con var AUTH_TOKEN nella tua testa. Dovrebbe essere qualcosa di simile.

<%= csrf_meta_tag %> 
<%= javascript_tag "var AUTH_TOKEN = '#{form_authenticity_token}';" if protect_against_forgery? %> 

E poi semplicemente mettere il vostro authenticity_token = auth_token nei dati Ajax se non è necessario utilizzare genitore (forma) o qualcosa di simile.

$.ajax({ 
    type: 'post', 
    dataType:'text', 
    data: "user_id="+user_id+"&authenticity_token="+AUTH_TOKEN, 
    url:'/follow/unfollow' 
}) 

Grazie ai ragazzi sopra per condividere questa conoscenza!

+1

Il token di autenticazione è codificato in base 64. Può contenere un segno più (+). Se non si esegue correttamente l'escape del token di autenticazione, i file di rails lo analizzeranno come spazio, a causa della codifica dell'URL . – iblue

3

Ho appena incontrato questo problema, ma ho provato questo approccio nel mio file application.js:

$(document).ajaxSend(function(e, xhr, options) { 
    if (options.data == null) { 
    options.data = {}; 
    } 
    options.data['authenticity_token'] = token; 
}); 

Questa è la domanda originale in cui ho avuto l'idea: ajaxSend Question

20

Questo token anche appare già in uno dei tag "meta" nella testa dell'applicazione.html.file di layout erb per difetto se avete la seguente ERB in alto:

<%= csrf_meta_tag %> 

Che ERB rende grosso modo:

<meta content="abc123blahblahauthenticitytoken" name="csrf-token"> 

È quindi possibile afferrare utilizzando jQuery con il seguente codice:

var AUTH_TOKEN = $('meta[name=csrf-token]').attr('content'); 
13

Nessuno di questi ha lavorato per me fino a quando ho impostato il valore X-CSRF-Token sull'intestazione richiesta via JS come questo:

request.setRequestHeader('X-CSRF-Token', token) 

token ovviamente, essendo il token CSRF. Ho ottenuto questo dal tag <meta name="csrf-token"> e non ho usato encodeURIComponent()

aggiornamento dal momento che questo si sta rivelando utile a qualche

Quindi, tutto sommato:

var token = document.querySelector('meta[name="csrf-token"]').content 
request.setRequestHeader('X-CSRF-Token', token) 
0

Semplicemente usando form_tag automaticamente include parametro token CSRF . Rails supporta "Javascript non intrusivo", il che significa che il modulo verrà comunque inviato tramite AJAX. Le azioni del controller supportano il blocco "respond_to" e puoi utilizzare l'estensione .js.erb per apportare modifiche alla pagina web in risposta al modulo submit.