rails invalidauthenticitytoken authenticity ruby-on-rails ruby-on-rails-4

ruby on rails - Rails4 ActionController:: InvalidAuthenticityToken error



ruby actioncontroller:: invalidauthenticitytoken (6)

Tengo la aplicación Rails4 ejecutándose en producción, y mis visitantes se ejecutan ocasionalmente en el error ActionController :: InvalidAuthenticityToken, que no puedo reproducir. Recibo 2-4 notificaciones diarias de varias formas, sin una lógica clara detrás. El informe que recibo muestra que authenticity_token enviado por el formulario es diferente de uno que se mantiene en sesión. ¿Como es posible? Me las arreglé para encontrar el problema varias veces, sin embargo es imposible de reproducir, todo de repente la autenticidad_token para el formulario es diferente de la almacenada en sesión y surge InvalidAuthenticityToken.
alguna idea de donde comenzar a buscar?

Ejemplo:

Request: ------------------------------- * URL : https://domain/signin * HTTP Method: POST * IP address : 113.96.xx.xx * Parameters : {"utf8"=>"✓", "authenticity_token"=>"MOh9JDE1AZ0CbIw/M33vfhjRShwzI6oqMhi8lk+n7OE=", "email"=>"xxxx@xxx", "password"=>"[FILTERED]", "commit"=>"Sign In", "controller"=>"clients", "action"=>"signin", "locale"=>"en"} ------------------------------- Session: ------------------------------- * session id: [FILTERED] * data: {"_csrf_token"=>"QazCSVGeZlxEh83XTM+f5PkC/zopwCF96yV4duRats0="}

Actualización: quería agregar que estoy publicando las páginas mediante dos instancias de AWS EC2 con equilibrio de carga y almacenar sesiones en la instancia de Redis ElastiCache


Como rails usa JavaScript para anexar los authenticity_token a rails, compruebo doblemente que no tiene un error JS en tiempo de ejecución basado en el contenido dinámico que está causando este heisenbug. Si se produce un error JS, debemos romper todo el archivo application.js, sus formularios no serán válidos. es posible?


Cualquier formulario generado por Rails (es decir, con form_for y such, no con usted poniendo <form> en la plantilla) tendrá el token anti-CSRF agregado como un campo oculto cuando sea necesario. Si escribió el formulario usted mismo y no incluyó la entrada oculta de CSRF, entonces Rails confía en la metaetiqueta CSRF y JavaScript para que todo funcione. Entonces, si escribió su propio formulario y no incluyó el campo oculto, y si el JavaScript del cliente no funciona por el motivo que sea, puede obtener este error. Debido a que la cláusula de "JavaScript del cliente no funciona por cualquier motivo" es difícil de detectar y depurar, en realidad eliminé intencionadamente la metaetiqueta CSRF en mi sitio. De esa manera, si olvidé incluir la entrada oculta, se romperá para todos (falla rápida), me enteraría de ello inmediatamente y podría solucionarlo. Yo recomendaría que hicieras esto también.

Habiendo dicho eso, recomendaría que miraras el registro de acceso para estos "visitantes". ¿Ves algo extraño?

  • ¿Acceden a la página que tiene el formulario inmediatamente antes de enviarla? Si no, tal vez sean bots o intentos reales de CSRF (eso es lo que está buscando, ¿no? :)).
  • ¿Cargaron el formulario en un EC2 y terminaron enviando a otro? Si es así, ¿puedes apagar un EC2 y ver si los errores desaparecen?
  • ¿Perdieron de alguna manera su sesión? Este podría ser tu problema o el de ellos.

Que ocurra al iniciar sesión me hace sospechar que algo puede estar mal al cerrar la sesión, lo que desencadena el problema para los usuarios que se desconectan y vuelven a conectarse de inmediato.

Cerrar sesión normalmente destruye la sesión actual del usuario y la reemplaza por una nueva, invalidando la etiqueta CSRF. Por lo general, esto no es un problema, ya que el usuario se redirige a otra página que contiene la nueva etiqueta CSRF.

Puedo ver que esto es un problema si

  • El cierre de sesión conduce a una página que puede almacenarse en caché, ya sea en el navegador o en un proxy
  • El cierre de sesión se realiza a través de AJAX, que en casos excepcionales falla al hacer lo correcto en caso de éxito y no actualiza la etiqueta CSRF.

Para responder a mi propia pregunta, en caso de que alguien se encuentre con el mismo problema, parece que eliminar csrf_meta_tag del encabezado nos solucionó el problema. No sé por qué. Podría ser que los rails javascript responsables de configurar el auth_token estuvieran interfiriendo de alguna manera con nuestro javascript y causaron el problema, pero mi instinto me dice que tenía que tener algo con el caché, ya sea en el servidor o en el lado del cliente. De todos modos, después de eliminar csrf_meta_tag, parece que nos deshicimos del problema. Solo asegúrate de estar usando form_tag para todos tus formularios.


Tuve el mismo problema. Servidor: nginx + pasajero

nginx.conf:

http { ... expires 90d; ... server { server_name domain1.com ... } server { server_name domain2.com ... } server { server_name domain_3_with_rails.com ... } }

Los problemas en la instrucción "vence 90d;" Navegador en la página localmente en caché con formulario y con authenticity_token.

Solución: agregue "expires 0d;" para dominios de rieles:

nginx.conf:

http { ... expires 90d; ... server { server_name domain1.com ... } server { server_name domain2.com ... } server { server_name domain_3_with_rails.com expires 0d; ... } }

Después de eso, asegúrese de reiniciar Nginx.

Para aquellos que tienen apache: apache ciertamente tiene una declaración similar "expira" para nginx


Tengo el mismo problema que ahora. He estado hurgando y noté que si desactivaba las cookies (bloqueaba el dominio para poder usar las cookies) me toparé con un ActionController :: InvalidAuthenticityToken cada vez que hago un POST .

Entonces el usuario tiene JS habilitado pero no permite cookies.

AFAIK el token anti-CSRF en Rails se envía como un lado del servidor de cookies de sesión, y luego falla ya que no se pudo establecer la cookie.