Deviazione del reindirizzamento dopo il login fallito

Tutte le domande che ho trovato sono correlate per un login riuscito con l’helper after_sign_in_path_for(resource)

Ho un modulo di accesso nell’indice del sito, e quando l’accesso fallisce, reindirizza a “users / sign_in”

Ma come posso redirect al mio “sito # index” quando l’accesso fallisce?

  1. Crea un file custom_failure.rb nella directory lib con:

     class CustomFailure < Devise::FailureApp def redirect_url your_path end def respond if http_auth? http_auth else redirect end end end 
  2. Nel tuo inizializzatore Devise, includi:

      config.warden do |manager| manager.failure_app = CustomFailure end 
  3. Assicurati che Rails sia caricato nei tuoi file lib, nel tuo application.rb:

     config.autoload_paths += %W(#{config.root}/lib) 

Non dimenticare di riavviare il tuo server.

Non penso che ci sia un modo più semplice per farlo. In bocca al lupo.

Se usi il tuo SessionsController , puoi riassegnare il valore :recall di auth_options per richiamare il controller#method prima di eseguire warden.authenticate!(auth_options) , ad esempio:

in app / controller / utenti / sessioni_controller.rb

 class Users::SessionsController < Devise::SessionsController #... def create #... auth_options = { :recall => 'site#index', :scope => :user } resource = warden.authenticate!(auth_options) #... end #... end 

In questo modo, non è necessario creare la FailureApp personalizzata e modificare le configurazioni.

Questo è ciò che accade con Devise 3.1.0

 Started POST "/users/sign_in" Processing by Devise::SessionsController#create Completed 401 Unauthorized Processing by Devise::SessionsController#new 

viene chiamato new a causa delle auth_options definite alla fine di gems / devise-3.1.0 / app / controller / devise / sessions_controller.rb

È necessario ridefinire le opzioni auth utilizzate nell’azione create. Ho copiato il controller in app / controller / devise / sessions_controller.rb della mia applicazione Rails e ho sostituito il metodo auth_options come questo

 def auth_options { :scope => resource_name, :recall => "Home#new" } end 

Fa il trucco, ma l’url è ancora / users / sign_in

Proverò a risolvere anche questo.

È ansible modificare il percorso predefinito sign_in.

Controlla https://github.com/plataformatec/devise/wiki/How-To:-Change-the-default-sign_in-and-sign_out-routes

Sulla base della risposta di Marcao, consiglio vivamente di posizionare un debugger nel metodo di risposta CustomFailure per capire meglio cosa sta succedendo.

 Class CustomFailure < Devise::FailureApp def respond binding.pry super end end 

Se si guarda il codice sorgente DeviseApp FailureApp per il metodo di risposta è molto facile capire cosa sta succedendo.

 def respond if http_auth? http_auth elsif warden_options[:recall] recall else redirect end end 

Ad esempio, per restituire un redirect_url, è necessario assicurarsi che i condizionali del codice di respond alla fine restituiscano il redirect .

Tuttavia, se si desidera restituire uno stato 401 standard come definito nel metodo http_auth , si desidera verificare che il codice del metodo di respond restituisca http_auth .

Quindi vale la pena esaminare la definizione di http_auth? In particolare, si noti la: request.xhr? metodo, che restituirà 0 per richieste json (ricorda che 0 in realtà è true in ruby)

 def http_auth? if request.xhr? Devise.http_authenticatable_on_xhr else !(request_format && is_navigational_format?) end end 

E forse controlla i tuoi inizializzatori / file di config.http_authenticatable_on_xhr per config.http_authenticatable_on_xhr o config.navigational_formats per controllare la risposta che desideri. Questa configurazione può davvero influire su ciò che Devise ritorna e può spesso portare a comportamenti imprevisti a causa di ciò che fa qui sotto il cofano.