rails invalidauthenticitytoken authenticity ruby-on-rails devise safari csrf

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