Forma correcta de enviar un Token de Autenticidad con AJAX..?


Esto funciona pero se detiene porque carece de un token de autenticidad:

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

Así que intenté añadirlo así:

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

Y pasa el auth_token correctamente como un param, pero parece perder el resto de mi forma.

De todos modos para lograr tanto el envío de los datos del formulario que funciona, y el token de autenticidad, así?

Este es un entorno rails. Y tengo esto en mi cabeza.

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

Cosas que he intentado

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 );
    }
});
Author: Trip, 2011-09-27

7 answers

En realidad, estás leyendo el atributo action de form y enviándole una solicitud post ajax. para enviar los datos del formulario tienes que enviar el formulario o puedes serializar los datos del formulario y enviarlos en ajax request como

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

Hacer esto serializará los datos de su formulario y lo enviará junto con la solicitud ajax y el token de autenticidad ya se está enviando a través de la cadena de consulta

 29
Author: Muhammad Adeel Zahid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-27 12:40:28

Este token también aparece en una de las etiquetas "meta" en el encabezado de la aplicación.HTML.archivo de diseño ERB por defecto si tiene el siguiente ERB en la parte superior:

<%= csrf_meta_tag %>

Que ERB representa aproximadamente a:

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

Luego puede grabarlo usando jQuery con el siguiente código:

var AUTH_TOKEN = $('meta[name=csrf-token]').attr('content');
 22
Author: omdel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-17 23:21:37

Ninguno de estos funcionó para mí hasta que establecí el valor X-CSRF-Token en el encabezado de la solicitud a través de JS de esta manera:

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

token por supuesto, siendo el token de la CSRF. Obtuve esto de la etiqueta <meta name="csrf-token"> y no usé encodeURIComponent()

Actualizar ya que esto está demostrando ser útil para algunos

Así que en conjunto:

var token = document.querySelector('meta[name="csrf-token"]').content
request.setRequestHeader('X-CSRF-Token', token)
 16
Author: Adam Grant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-23 19:30:01

Gracias!

Solo para aclarar para el uso más común.

Necesitas la etiqueta js con var AUTH_TOKEN en tu cabeza. Debería ser algo como esto.

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

Y luego simplemente ponga su authenticity_token=AUTH_TOKEN en los datos ajax si no necesita usar padre(formulario) o algo como esto.

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

Gracias a los chicos de arriba por compartir este conocimiento!

 15
Author: Yavor Ivanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-03 09:26:42

Podría incluir el AUTH_TOKEN en el propio formulario, como una entrada oculta.

<input type="hidden" name="AUTH_TOKEN">1234abcd</input>
 3
Author: BishopRook,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-26 20:22:28

Me encontré con este problema, pero probé este enfoque en mi solicitud.archivo js:

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

Esta es la pregunta original de donde obtuve la idea: ajaxSend Question

 3
Author: carnator,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:13

Simplemente usando form_tag incluye automáticamente el parámetro token CSRF. Rails admite "Javascript discreto", lo que significa que el formulario seguirá enviándose a través de AJAX. Las acciones del controlador soportan el bloque "respond_to", y se puede usar .js.extensión erb para realizar cambios en la página web en respuesta al envío del formulario.

 0
Author: wondersz1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-08 21:25:38