ruby-on-rails jquery csrf

ruby on rails - ADVERTENCIA: No se pueden verificar los carriles de autenticidad del token CSRF



ruby-on-rails jquery (17)

Estoy enviando datos desde la vista al controlador con AJAX y recibí este error:

ADVERTENCIA: No se puede verificar la autenticidad del token CSRF

Creo que tengo que enviar este token con datos.

¿Alguien sabe cómo puedo hacer esto?

Editar: mi solucion

Hice esto poniendo el siguiente código dentro de la publicación de AJAX:

headers: { ''X-Transaction'': ''POST Example'', ''X-CSRF-Token'': $(''meta[name="csrf-token"]'').attr(''content'') },


  1. Asegúrate de tener <%= csrf_meta_tag %> en tu diseño
  2. Agregue un beforeSend para incluir el token csrf en la solicitud ajax para establecer el encabezado. Esto solo es necesario para post solicitudes de post .

El código para leer el token csrf está disponible en rails/jquery-ujs , por lo que es más fácil usarlo de la siguiente manera:

$.ajax({ url: url, method: ''post'', beforeSend: $.rails.CSRFProtection, data: { // ... } })


De hecho la forma más sencilla. No te molestes en cambiar los encabezados.

Asegúrate de tener:

<%= csrf_meta_tag %> in your layouts/application.html.erb

Solo haz un campo de entrada oculto como este:

<input name="authenticity_token" type="hidden" value="<%= form_authenticity_token %>"/>

O si quieres un post de jQuery ajax:

$.ajax({ type: ''POST'', url: "<%= someregistration_path %>", data: { "firstname": "text_data_1", "last_name": "text_data2", "authenticity_token": "<%= form_authenticity_token %>" }, error: function( xhr ){ alert("ERROR ON SUBMIT"); }, success: function( data ){ //data response can contain what we want here... console.log("SUCCESS, data="+data); } });


Estoy usando Rails 4.2.4 y no pude entender por qué estaba recibiendo:

Can''t verify CSRF token authenticity

Tengo en el diseño:

<%= csrf_meta_tags %>

En el controlador:

protect_from_forgery with: :exception

Al invocar tcpdump -A -s 999 -i lo port 3000 se mostraba la configuración del encabezado (a pesar de no tener que configurar los encabezados con ajaxSetup , ya estaba hecho):

X-CSRF-Token: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest DNT: 1 Content-Length: 125 authenticity_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Al final estaba fallando porque tenía las cookies desactivadas. CSRF no funciona sin que las cookies estén habilitadas, por lo que esta es otra causa posible si está viendo este error.


La actualización de una aplicación anterior a Rails 3.1, incluida la metaetiqueta csrf, todavía no lo resuelve. En el blog rubyonrails.org, brindan algunos consejos de actualización, y específicamente esta línea de jQuery, que debe ir en la sección principal de su diseño:

$(document).ajaxSend(function(e, xhr, options) { var token = $("meta[name=''csrf-token'']").attr("content"); xhr.setRequestHeader("X-CSRF-Token", token); });

tomado de esta entrada del blog: http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails .

En mi caso, la sesión se estaba restableciendo en cada solicitud ajax. Añadiendo el código anterior se solucionó ese problema.


La mejor manera de hacer esto es en realidad simplemente usar <%= form_authenticity_token.to_s %> para imprimir el token directamente en su código de rieles. No es necesario usar javascript para buscar el token csrf en el dom como mencionan otras publicaciones. simplemente agregue la opción de encabezados como se muestra abajo;

$.ajax({ type: ''post'', data: $(this).sortable(''serialize''), headers: { ''X-CSRF-Token'': ''<%= form_authenticity_token.to_s %>'' }, complete: function(request){}, url: "<%= sort_widget_images_path(@widget) %>" })


Las respuestas más votadas aquí son correctas, pero no funcionarán si está realizando solicitudes de dominios cruzados porque la sesión no estará disponible a menos que indique explícitamente a jQuery que pase la cookie de sesión. Aquí está cómo hacer eso:

$.ajax({ url: url, type: ''POST'', beforeSend: function(xhr) { xhr.setRequestHeader(''X-CSRF-Token'', $(''meta[name="csrf-token"]'').attr(''content'')) }, xhrFields: { withCredentials: true } });


Luché con este tema durante días. Cualquier llamada GET estaba funcionando correctamente, pero todos los PUT generarían un error "No se puede verificar la autenticidad del token CSRF". Mi sitio web funcionaba bien hasta que agregué un certificado SSL a nginx.

Finalmente me topé con esta línea faltante en mi configuración de nginx:

location @puma { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_set_header X-Forwarded-Proto https; # Needed to avoid ''WARNING: Can''t verify CSRF token authenticity'' proxy_pass http://puma; }

Después de agregar la línea que falta "proxy_set_header X-Forwarded-Proto https;", todos los errores de token de CSRF se cerraron.

Esperemos que esto ayude a alguien que también se está golpeando la cabeza contra una pared. jaja


Para aquellos de ustedes que necesitan una respuesta no jQuery, pueden agregar simplemente lo siguiente:

xmlhttp.setRequestHeader(''X-CSRF-Token'', $(''meta[name="csrf-token"]'').attr(''content''));

Un ejemplo muy simple puede ser enviado aquí:

xmlhttp.open("POST","example.html",true); xmlhttp.setRequestHeader(''X-CSRF-Token'', $(''meta[name="csrf-token"]'').attr(''content'')); xmlhttp.send();


Puedes escribirlo globalmente como abajo.

JS normal:

$(function(){ $(''#loader'').hide() $(document).ajaxStart(function() { $(''#loader'').show(); }) $(document).ajaxError(function() { alert("Something went wrong...") $(''#loader'').hide(); }) $(document).ajaxStop(function() { $(''#loader'').hide(); }); $.ajaxSetup({ beforeSend: function(xhr) {xhr.setRequestHeader(''X-CSRF-Token'', $(''meta[name="csrf-token"]'').attr(''content''))} }); });

Guión de café:

$(''#loader'').hide() $(document).ajaxStart -> $(''#loader'').show() $(document).ajaxError -> alert("Something went wrong...") $(''#loader'').hide() $(document).ajaxStop -> $(''#loader'').hide() $.ajaxSetup { beforeSend: (xhr) -> xhr.setRequestHeader(''X-CSRF-Token'', $(''meta[name="csrf-token"]'').attr(''content'')) }



Si está utilizando javascript con jQuery para generar el token en su formulario, esto funciona:

<input name="authenticity_token" type="hidden" value="<%= $(''meta[name=csrf-token]'').attr(''content'') %>" />

Obviamente, necesitas tener el <%= csrf_meta_tag %> en tu diseño de Ruby.


Si no está utilizando jQuery y está utilizando algo como la API de fetch para las solicitudes, puede usar lo siguiente para obtener el csrf-token :

document.querySelector(''meta[name="csrf-token"]'').getAttribute(''content'')

fetch(''/users'', { method: ''POST'', headers: { ''Accept'': ''application/json'', ''Content-Type'': ''application/json'', ''X-CSRF-Token'': document.querySelector(''meta[name="csrf-token"]'').getAttribute(''content'')}, credentials: ''same-origin'', body: JSON.stringify( { id: 1, name: ''some user'' } ) }) .then(function(data) { console.log(''request succeeded with JSON response'', data) }).catch(function(error) { console.log(''request failed'', error) })


Si recuerdo correctamente, debe agregar el siguiente código a su formulario para deshacerse de este problema:

<%= token_tag(nil) %>

No olvides el parámetro.



Usted debe hacer esto:

  1. Asegúrate de tener <%= csrf_meta_tag %> en tu diseño

  2. Agregue beforeSend a todas las solicitudes de ajax para establecer el encabezado como se muestra a continuación:

$.ajax({ url: ''YOUR URL HERE'', type: ''POST'', beforeSend: function(xhr) {xhr.setRequestHeader(''X-CSRF-Token'', $(''meta[name="csrf-token"]'').attr(''content''))}, data: ''someData='' + someData, success: function(response) { $(''#someDiv'').html(response); } });

Para enviar token en todas las solicitudes puedes usar:

$.ajaxSetup({ headers: { ''X-CSRF-Token'': $(''meta[name="csrf-token"]'').attr(''content'') } });


Utilice jquery.csrf ( https://github.com/swordray/jquery.csrf ).

  • Rieles 5.1 o posteriores

    $ yarn add jquery.csrf

    //= require jquery.csrf

  • Carriles 5.0 o antes

    source ''https://rails-assets.org'' do gem ''rails-assets-jquery.csrf'' end

    //= require jquery.csrf

  • Código fuente

    (function($) { $(document).ajaxSend(function(e, xhr, options) { var token = $(''meta[name="csrf-token"]'').attr(''content''); if (token) xhr.setRequestHeader(''X-CSRF-Token'', token); }); })(jQuery);


Uy ..

Me perdí la siguiente línea en mi aplicación.js

//= require jquery_ujs

Lo reemplacé y está funcionando.

======= ACTUALIZADO =========

Después de 5 años, volví con el mismo error, ahora tengo Rails 5.1.6 completamente nuevos y encontré esta publicación nuevamente. Al igual que el círculo de la vida.

Ahora, ¿cuál fue el problema ?: Rails 5.1 eliminó el soporte para jquery y jquery_ujs de forma predeterminada, y agregó

//= require rails-ujs in application.js

Hace las siguientes cosas:

  1. forzar los diálogos de confirmación para diversas acciones;
  2. realizar solicitudes no GET desde hipervínculos;
  3. Haga que los formularios o hipervínculos envíen datos de forma asíncrona con Ajax;
  4. hacer que los botones de envío se desactiven automáticamente en el formulario enviado para evitar hacer doble clic (desde: https://github.com/rails/rails-ujs/tree/master )

Pero, ¿por qué no incluye el token csrf para la solicitud ajax? Si alguien sabe de esto en detalle solo comentame. Soy consciente de que.

De todos modos, agregué lo siguiente en mi archivo js personalizado para que funcione (Gracias por otras respuestas para ayudarme a alcanzar este código):

$( document ).ready(function() { $.ajaxSetup({ headers: { ''X-CSRF-Token'': Rails.csrfToken() } }); ---- ---- });