web-dev-qa-db-fra.com

Moyen approprié d’envoyer un jeton d’authenticité avec AJAX ..?

Cela fonctionne mais est arrêté car il manque un jeton d'authenticité:

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

Alors j'ai essayé de l'ajouter comme ça:

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

Et il passe correctement l'auth_token en tant que paramètre, mais semble perdre le reste de ma forme.

Quoi qu'il en soit, pour envoyer à la fois les données de formulaire qui fonctionnent et le jeton d'authenticité également?

Ceci est un environnement Rails. Et j'ai ça dans la tête.

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

Ce que j'ai essayé

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 );
    }
});
37
Trip

En fait, vous lisez l'attribut action du formulaire et vous lui envoyez une requête post ajax. pour envoyer des données de formulaire, vous devez soumettre le formulaire ou vous pouvez sérialiser les données de formulaire et les envoyer en requête ajax, comme

$(".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;
});

Cela va sérialiser vos données de formulaire et les envoyer avec la requête ajax et le jeton d'authenticité est déjà envoyé via une chaîne de requête.

29

Ce jeton apparaît également déjà dans l'une des balises "meta" dans l'en-tête du fichier de mise en forme application.html.erb par défaut si vous avez l'ERB suivant en haut:

<%= csrf_meta_tag %>

Cet ERB rend à peu près à:

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

Vous pouvez ensuite le récupérer en utilisant jQuery avec le code suivant:

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

Aucune de ces solutions ne fonctionnait pour moi jusqu'à ce que je définisse la valeur X-CSRF-Token dans l'en-tête de la requête via JS, comme ceci:

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

token bien sûr, étant le jeton CSRF. Je l'ai eu avec la balise <meta name="csrf-token"> et je n'ai pas utilisé encodeURIComponent()

Mise à jour puisque cela s'avère utile pour certains

Donc en somme:

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

Merci!

Juste pour clarifier pour l'utilisation plus commune.

Vous avez besoin de la balise js avec la variable AUTH_TOKEN dans votre tête. Devrait être quelque chose comme ça.

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

Et ensuite, mettez simplement authenticity_token = AUTH_TOKEN dans les données ajax si vous n'avez pas besoin d'utiliser parent (formulaire) ou quelque chose comme ça.

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

Merci aux gars ci-dessus pour partager cette connaissance!

15
Yavor Ivanov

Je viens de rencontrer ce problème, mais j'ai essayé cette approche dans mon fichier application.js:

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

C’est la question initiale où j’ai eu l’idée: ajaxSend Question

3
carnator

Vous pouvez inclure AUTH_TOKEN dans le formulaire lui-même, en tant qu'entrée masquée.

<input type="hidden" name="AUTH_TOKEN">1234abcd</input>
3
BishopRook

Le simple fait d'utiliser form_tag inclut automatiquement le paramètre de jeton CSRF. Rails prend en charge le "Javascript non intrusif", ce qui signifie que le formulaire sera toujours envoyé via AJAX. Les actions du contrôleur prennent en charge le bloc "respond_to" et vous pouvez utiliser l'extension .js.erb pour modifier la page Web en réponse à l'envoi du formulaire. 

0
wondersz1