Si la protect_from_forgery
opción se menciona en application_controller, puedo iniciar sesión y realizar cualquier solicitud GET, pero en la primera solicitud POST Rails restablece la sesión, lo que me desconecta.
protect_from_forgery
Desactivé la opción temporalmente, pero me gustaría usarla con Angular.js. ¿Hay alguna forma de hacer eso?
Respuestas:
Creo que leer el valor CSRF de DOM no es una buena solución, es solo una solución.
Aquí hay un documento del sitio web oficial angularJS http://docs.angularjs.org/api/ng.$http :
Aquí está mi solución basada en esas instrucciones:
Primero, configure la cookie:
Luego, debemos verificar el token en cada solicitud que no sea GET.
Como Rails ya ha construido con un método similar, simplemente podemos anularlo para agregar nuestra lógica:
fuente
Si está utilizando la protección CSRF Rails predeterminada (
<%= csrf_meta_tags %>
), puede configurar su módulo angular de esta manera:O, si no estás usando CoffeeScript (¿qué?):
Si lo prefiere, puede enviar el encabezado solo en solicitudes no GET con algo como lo siguiente:
Además, asegúrese de consultar la respuesta de HungYuHei , que cubre todas las bases del servidor en lugar del cliente.
fuente
<%= csrf_meta_tags %>
. Pensé que debería haber suficiente para mencionarprotect_from_forgery
solo. ¿Qué hacer? El documento base debe ser un HTML simple (aquí no soy el que elige).protect_from_forgery
lo que dice es "cuando mi código JavaScript hace solicitudes Ajax, prometo enviar unX-CSRF-Token
encabezado que corresponda al token CSRF actual". Para obtener este token, Rails lo inyecta en el DOM<%= csrf_meta_token %>
y obtiene el contenido de la metaetiqueta con jQuery cada vez que realiza solicitudes Ajax (el controlador UJS predeterminado de Rails 3 lo hace por usted). Si no está utilizando ERB, no hay forma de obtener el token actual de Rails en la página y / o el JavaScript, por lo que no puede usarloprotect_from_forgery
de esta manera.csrf_meta_tags
cada vez que el servidor genera una respuesta, y cada vez que estas etiquetas son diferentes de las anteriores. Por lo tanto, estas etiquetas son únicas para cada solicitud. La pregunta es: ¿cómo recibe la aplicación estas etiquetas para una solicitud AJAX (sin angular)? Utilicé protect_from_forgery con solicitudes jQuery POST, nunca me molesté en obtener este token CSRF, y funcionó. ¿Cómo?jQuery.ajaxPrefilter
como se muestra aquí: github.com/indirect/jquery-rails/blob/c1eb6ae/vendor/assets /... Puede leer detenidamente este archivo y ver todos los aros que Rails salta para que funcione bastante sin tener que Preocúpate por eso.put
ypost
en lugar de sobrecommon
? De la guía de seguridad de rieles :The solution to this is including a security token in non-GET requests
La gema angular_rails_csrf agrega automáticamente soporte para el patrón descrito en la respuesta de HungYuHei a todos sus controladores:
fuente
angular_rails_csrf
gema no funciona con Rails 5. Sin embargo, ¡la configuración de encabezados de solicitud angular con el valor de la metaetiqueta CSRF funciona!La respuesta que combina todas las respuestas anteriores y confía en que está utilizando la
Devise
gema de autenticación.En primer lugar, agrega la gema:
Luego, agregue el
rescue_from
bloque en application_controller.rb:Y finalmente, agregue el módulo interceptor a su aplicación angular.
fuente
$injector
lugar de inyectar directamente$http
?Vi las otras respuestas y pensé que eran geniales y bien pensadas. Sin embargo, conseguí que mi aplicación de rieles funcionara con lo que pensé que era una solución más simple, así que pensé en compartir. Mi aplicación de rieles vino con esto predeterminado,
Leí los comentarios y parecía que eso es lo que quiero usar angular y evitar el error csrf. Lo cambié a esto,
¡Y ahora funciona! No veo ninguna razón por la que esto no debería funcionar, pero me encantaría saber algo de otros carteles.
fuente
He usado el contenido de la respuesta de HungYuHei en mi aplicación. Sin embargo, descubrí que estaba lidiando con algunos problemas adicionales, algunos debido a mi uso de Devise para la autenticación, y algunos debido al valor predeterminado que obtuve con mi aplicación:
Tomé nota de la pregunta relacionada con el desbordamiento de la pila y las respuestas allí , y escribí una publicación de blog mucho más detallada que resume las diversas consideraciones. Las partes de esa solución que son relevantes aquí son, en el controlador de la aplicación:
fuente
Encontré un truco muy rápido para esto. Todo lo que tuve que hacer es lo siguiente:
a. En mi opinión, inicializo una
$scope
variable que contiene el token, digamos antes del formulario, o incluso mejor en la inicialización del controlador:si. En mi controlador AngularJS, antes de guardar mi nueva entrada, agrego el token al hash:
No se necesita hacer nada más.
fuente
¡Está trabajando en el lado angularjs!
fuente