Token de Autenticidad Rails 4


Estaba trabajando en una nueva aplicación Rails 4 (en Ruby 2.0.0-p0) cuando me encontré con algunos problemas de tokens de autenticidad.

Mientras escribía un controlador que respondía a json (usando el método de clase respond_to), llegué a la acción create Comencé a obtener excepciones ActionController::InvalidAuthenticityToken cuando intenté crear un registro usando curl.

Me aseguré de establecer -H "Content-Type: application/json" y establecer los datos con -d "<my data here>" pero todavía no hay suerte.

Intenté escribir el mismo controlador usando Rails 3.2 (en Ruby 1.9.3) y no conseguí problemas de autenticidad en absoluto. Busqué y vi que había algunos cambios con los tokens de autenticidad en Rails 4. Por lo que entiendo, ¿ya no se insertan automáticamente en los formularios? Supongo que esto está afectando de alguna manera a los tipos de contenido no HTML.

¿Hay alguna manera de evitar esto sin tener que solicitar un formulario HTML, arrebatando el token de autenticidad y luego haciendo otra solicitud con ese token? O me estoy perdiendo algo que es completamente obvio?

Edit: Acabo de intentar crear un nuevo registro en una nueva aplicación Rails 4 usando un scaffold sin cambiar nada y me estoy topando con el mismo problema, así que supongo que no es algo que haya hecho.

Author: John Bachir, 0000-00-00

5 answers

Creo que acabo de averiguarlo. Cambié el (nuevo) predeterminado

protect_from_forgery with: :exception

A

protect_from_forgery with: :null_session

Según el comentario en ApplicationController.

# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.

Puedes ver la diferencia mirando la fuente de request_forgery_protecton.rb, o, más específicamente, las siguientes líneas:

En Carriles 3.2:

# This is the method that defines the application behavior when a request is found to be unverified.
# By default, \Rails resets the session when it finds an unverified request.
def handle_unverified_request
  reset_session
end

En Carriles 4:

def handle_unverified_request
  forgery_protection_strategy.new(self).handle_unverified_request
end

Que llamará lo siguiente :

def handle_unverified_request
  raise ActionController::InvalidAuthenticityToken
end
 271
Author: alexcoco,
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
2014-09-05 16:26:45

En lugar de desactivar la protección csrf, es mejor agregar la siguiente línea de código en el formulario

<%= tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token) %> 

Y si está utilizando form_for o form_tag para generar el formulario, entonces agregará automáticamente la línea de código anterior en el formulario

 69
Author: xiaoboa,
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-10-23 04:00:03

Agregar la siguiente línea en el formulario funcionó para mí:

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
 68
Author: Carlos,
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-05-24 23:56:44

No creo que sea bueno desactivar generalmente la protección CSRF siempre y cuando no implemente exclusivamente una API.

Al mirar la documentación de la API de Rails 4 para ActionController encontré que puede desactivar la protección contra falsificaciones en una base por controlador o por método.

Por ejemplo, para desactivar la protección CSRF para métodos que puede usar

class FooController < ApplicationController
  protect_from_forgery except: :index
 32
Author: roamingthings,
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
2015-08-27 01:47:23

Se encontró con la s

 8
Author: ,
Warning: date() expects parameter 2 to be long, string given in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61