2011-09-01 22 views
10

aquí mi problema,Rails 3.1 - CSRF ignorado?

Tengo una aplicación carriles de 3.1 y yo estoy tratando de hacer una petición AJAX pero me sale el mensaje de advertencia "ADVERTENCIA: no puede verificar la autenticidad CSRF token" ...

Dentro de mi diseño Tengo el método de ayuda "csrf_method_tag", y agregue el siguiente código javascript (no sé si es realmente necesario o no):

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

mi Gemfile contiene la gema jquery-rails (> = 1.0.12) y requiero jquery & jquery-ujs en la parte superior de mi application.js.

Incluso con eso, el mensaje sigue apareciendo. Olvidé algo?

Gracias por su ayuda.

+0

teniendo el mismo problema, y ​​después de iniciar sesión me desconecto si cambio de página (usando gemas conectables de y rpx). Háganos saber si resuelve este – Plattsy

+0

¿Se está enviando la misma cookie en los encabezados de la solicitud AJAX que se envió en la solicitud que cargó la página que realiza la solicitud? El token de CSRF se valida en sinfonía con la sesión actual, que se mantiene en otro encabezado (que debe enviarse automáticamente, pero puede que no esté en su caso). –

+0

Mira mi respuesta aquí: http://stackoverflow.com/questions/15239818/iframe-causes-cant-verify-csrf-token-authenticity-n-rails/15869772#15869772 – tinker

Respuesta

7

Lo que funcionó para mí, al trabajar sin formularios, es incluir el resultado de <%= form_authenticity_token %> en la carga útil de datos ajax. Así que hago algo así como lo que fue sugerido por tehprofessor en el html:

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

luego en la javascript:

tokentag = $('#tokentag').val() 
submitdata = { "authenticity_token": tokentag, ...+whatever else you need to include+...} 

luego llamar al $.ajax con submitdata.

7

Probablemente ni siquiera necesite esto en su código. La gema jquery-rails establece automáticamente el token CSRF en todas las solicitudes Ajax de forma predeterminada.

+0

Lo sé, pero incluso con la eliminación de javascript código, el token CSRF parece que aún se ignora ... –

+0

¿Está utilizando los raíles estándar 'form_for' y' form_tag' helpers, o está utilizando sus propias etiquetas HTML '

'? –

+0

No estoy usando formulario ... Utilizo las solicitudes para actualizar parciales o para obtener algunos JSON. –

0

¿Ha intentado utilizar un elemento de formulario oculto con token de autenticidad?

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

Estaba teniendo el mismo error, y eso lo resolvió. Fue porque no estaba usando los ayudantes de formulario integrados ...

+0

No, todavía no funciona ... Tengo que arreglar este problema antes de que termine la semana, te lo hago saber si encuentro algo ... –

9

Tuve exactamente el mismo problema. Estaba tratando de atrapar un evento de javascript (you_tube player completed) y Ajax de vuelta a mi servidor para avisarme. Obtenía:

WARNING: Can't verify CSRF token authenticity

cuando la llamada jQuery ajax llegaba a mi servidor. Agregué su corrección de código por encima de

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

y funciona bien. Creo que la única diferencia está en mi diseño tengo

<%= csrf_meta_tags %> 

y no csrf_method_tag ​​como usted ha mencionado en su puesto original.
Así que gracias por la corrección, estaba en la publicación original.

+2

** Por favor, no uses firmas o eslóganes en tus publicaciones. ** Leer [ la entrada de preguntas frecuentes] (http://stackoverflow.com/faq#signatures) para obtener más información. ¡Gracias! –

0

Una razón puede ser que realice una llamada AJAX antes de cargar el documento, por lo que JQuery no puede obtener el token CSRF.

1

¡Simplemente hazlo directamente en tu llamada AJAX y funcionará correctamente!

$.ajax({ 
      type: //method, 
      beforeSend: function(xhr){ 
       xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content')) 
      }, 
      url: //parameter, 
      dataType: 'html', 
      success: function(data, textStatus, jqXHR) { 
       // some code 
      } 
    }); 
0

El problema es que tendrá que obtener un nuevo token después de una petición Ajax post porque una vez que un símbolo se utiliza el fichero es invalidada. Aquí está el código para hacer esto:

En los carriles cada vez que se envía una respuesta Mensaje de añadir estos parámetros a la respuesta:

def someMethod: 
    result[:csrfParam] = request_forgery_protection_token 
    result[:csrfToken] = form_authenticity_token 
    render :json => result 
end 

Ahora en el lado JS, en la función de éxito de cada método POST que pueda llamar a esta función:

var setCsrfToken = function(param, token) { 
    if(param == null || token == null) { 
     console.error("New CSRF param/token not present"); 
    } 
    $("input[name='" + param + "']").val(token); 
} 

así:

setCsrfToken(result["csrfParam"], result["csrfToken"]); 

esta función se restablecerá todos los parámetros de autenticidad_token en todos los formularios POST para que la siguiente solicitud tenga un token válido. Debe asegurarse de que esto ocurra en cada llamada POST, de lo contrario continuará enfrentando este problema.

Además, CSRF no es para prevenir el clickjacking, es un ataque por separado, donde otro sitio web puede hacer que un usuario haga clic en un enlace que ejecuta una acción en su sitio web con la sesión del usuario.