ruby-on-rails - invalidauthenticitytoken - can''t verify csrf token authenticity ajax
El inicio de sesiĆ³n Rails/Devise no funciona en Safari(error 422/CSRF) (2)
El inicio de sesión funciona bien en Chrome, pero no funciona en Safari (o asumo otros navegadores Webkit). Aparece este mensaje de error después de iniciar sesión ("Se rechazó el cambio que deseaba. Tal vez intentó cambiar algo a lo que no tuvo acceso"):
De acuerdo con mis registros heroku, esto es lo que está sucediendo:
2016-12-07T14:14:23.778153+00:00 app[web.1]: Can''t verify CSRF token authenticity
2016-12-07T14:14:23.778899+00:00 app[web.1]: Completed 422 Unprocessable Entity in 2ms (ActiveRecord: 0.0ms)
2016-12-07T14:14:23.785544+00:00 app[web.1]:
2016-12-07T14:14:23.785547+00:00 app[web.1]: ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
Creo que estoy enviando el token CSRF adecuado, pero algo parece estar funcionando mal. Este es mi actual application_controller.rb
:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
after_action :flash_to_headers
# this is so that json requests don''t redirect without a user
before_action :authenticate_user!
# before_action :authenticate_user!, unless: request.format == :json
# before_action :user_needed, if: request.format == :json
before_action :set_paper_trail_whodunnit
before_action :set_global_search_variable
def set_global_search_variable
@q = Person.ransack(params[:q])
end
def user_needed
unless current_user
render json: { ''error'' => ''authentication error'' }, status: 401
end
end
def flash_to_headers
return unless request.xhr?
response.headers[''X-Message''] = flash_message if flash_message
response.headers[''X-Message-Type''] = flash_type.to_s if flash_type
flash.discard # don''t want the flash to appear when you reload page
end
private
def flash_message
[:error, :warning, :notice].each do |type|
return flash[type] unless flash[type].blank?
end
nil
end
def flash_type
[:error, :warning, :notice].each do |type|
return type unless flash[type].blank?
end
nil
end
(Cambiar protect_from_forgery with:
a null_session
solo causa un ciclo sin fin de regresar a la pantalla de inicio de sesión.)
Esta pregunta hace referencia a un problema similar, pero no analiza la complicación de Devise. Supuestamente, Devise ya maneja este problema, pero de alguna manera no está funcionando aquí. Muchas de estas respuestas tienen años, por lo que no estoy seguro de cuán relevantes serían hoy.
También intenté buscar errores en el repositorio actual de Devise Github, pero parece que no llego a ninguna parte con las sugerencias en esos hilos. Muchas sugerencias para editar el controlador de la aplicación, pero muchas veces parece que bloquea toda la aplicación.
Esta aplicación ejecuta Ruby 2.2.5 y Rails 4.2.7.1. ¿La actualización a Rails 5 ayudaría a resolver este problema?
También tiene una anulación existente (y probablemente hacky) para hacer cuentas de administrador; la persona se registra a través de Devise y luego recibe acceso de administrador a través de otro campo llamado approved
manualmente en el shell pqsl
. No estoy seguro de si eso podría estar relacionado.
La aplicación está en Github, para cualquiera que quiera echar un vistazo: https://github.com/yamilethmedina/kimball
Como resultado, mi problema fue resuelto por esta respuesta . No estaba en el controlador de la aplicación después de todo, sino en config/initializers/session_store.rb
.
Esta fue mi session_store
inicial:
Logan::Application.config.session_store :cookie_store, key: ''_cutgroup_session'', secure: (Rails.env.production? || Rails.env.staging?)
Después de investigar más, encontré esta sugerencia:
Rails.application.config.session_store :cookie_store, key: "_rails_session_#{Rails.env}", domain: all
Esto todavía no funcionó; sin embargo, daría un error 401 en los registros (en lugar de 422) y redirigiría a la página de inicio de sesión en lugar de mostrar la pantalla de error que capturé anteriormente.
Finalmente, Rails.application.config.session_store :cookie_store, key: "_rails_session_#{Rails.env}"
el domain: all
parte desde el final de Rails.application.config.session_store :cookie_store, key: "_rails_session_#{Rails.env}"
funcionó para mí en Safari (las cookies no se bloquearon en ningún punto del navegador). Ahora, puedo iniciar sesión cuando el proyecto se implementa en Heroku.
La recompensa era un precio muy alto para pagar, ¡pero al menos los comentaristas me ayudaron a aclarar mis ideas y encontrar una solución! Si alguien más se encuentra con esta pregunta y se le ocurre otra mejor, la votaré en su lugar, pero creo que ya la tengo.
tratar :
controller / application.rb
protect_from_forgery with: :null_session
y anula tu controlador del dispositivo
sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
skip_before_filter :verify_authenticity_token, :only => [:destroy]
end