2012-05-24 5 views
38

Sto creando un'applicazione Rails con Omniauth per il servizio di accesso. Per autenticare Google sto usando OmniAuth Google OAuth2 Strategy.Come salvare OmniAuth :: Strategies :: OAuth2 :: CallbackError?

Quando l'utente fa clic sul pulsante "Consenti l'accesso", tutto funziona correttamente. Tuttavia, quando l'utente fa clic sul pulsante "no grazie", viene generato l'errore seguente.

OmniAuth::Strategies::OAuth2::CallbackError 

Ho provato ad aggiungere il seguente codice di ripristino nel controller dell'applicazione.

class ApplicationController < ActionController::Base 
    rescue_from OmniAuth::Strategies::OAuth2::CallbackError, :with => 
    :omniauth_callback_error_handler 

protected 

def omniauth_callback_error_handler 
    redirect_to init_sign_in_users_path 
end 
end 

Ma senza fortuna.

Qualche idea?

Grazie :)

risposta

32

Questo accade perché l'autenticazione avviene in un middleware in modo che il controller non è coinvolto in esso. Questo è where the exception is raised e il codice chiamato è this

Penso che si può gestire questo tipo di errore definendo una richiamata in Omniauth initializer con questo tipo di codice

Omniauth.config do |config| 
    config.on_failure do 
    # your handling code invoked in the context of a rack app 
    end 
end 

In caso contrario v'è a commit di tre mesi fa, che introdurre questo comportamento

def redirect_to_failure 
    message_key = env['omniauth.error.type'] 
    new_path = "#{env['SCRIPT_NAME']}#{OmniAuth.config.path_prefix}/failure?message=#{message_key}" 
    Rack::Response.new(["302 Moved"], 302, 'Location' => new_path).finish 
end 

che stabilisce che in caso di errori l'utente viene reindirizzato a /auth/failure con un messaggio di errore, così si dovrebbe essere in grado di definire un percorso per quel percorso e gestirlo nella tua app. Tieni presente che ciò non accadrà in development mode quindi è necessario provarlo in altri Envs. Se ciò non accade in produzione, prova ad aggiornare la tua gemma omniauth alla versione 1.1.0

+16

1000.times.do puts "La ringrazio molto!" fine –

+1

Ho questo comportamento nella modalità di sviluppo .. – simo

+2

Ho ottenuto questo funzionamento utilizzando' OmniAuth' invece di 'Omniauth'. Sembra che la maiuscola sia stata modificata. – tyler

16

Ho risolto questo problema con il primo suggerimento di Fabio.

OmniAuth.config.on_failure = Proc.new do |env| 
    UsersController.action(:omniauth_failure).call(env) 
    #this will invoke the omniauth_failure action in UsersController. 
end 

Nel mio UsersController

class UsersController < ActionController::Base 
    def omniauth_failure 
    redirect_to init_sign_in_users_path 
    #redirect wherever you want. 
    end 
end 
+4

dove devo inserire il codice sopra Omniauth.config.on_failure = Proc.new do | env | "UsersController" .constantize.action (: omniauth_failure) .call (env) #questo invocherà l'azione omniauth_failure in UsersController. fine – regmiprem

+2

inserisce il codice nel file config/initializers/omniauth_failure_callback.rb. Ti suggerisco di usare il codice di Peter perché è veramente pulito. –

+2

@soundar, sebbene il codice di peter sia più pulito, il tuo codice funziona in ambiente di sviluppo come previsto nell'ambiente di sviluppo. Quindi +1 alla tua risposta. – mcmlxxxiii

61

È possibile impostare il proc on_failure nel inizializzatore omniauth in maniera ancora più pulito:

OmniAuth.config.on_failure = UsersController.action(:oauth_failure) 
+4

+1 in quanto il codice sembra più pulito. –

+1

Grazie per questa soluzione pulita! ;) – Dmitri

+3

Questo codice funziona benissimo nell'ambiente di produzione. Tuttavia, se si modifica il codice UsersController # oauth_failure nell'ambiente di sviluppo, non verranno visualizzate modifiche. Il codice del soundar basato su Proc è migliore nello sviluppo e funziona come previsto nello sviluppo. – mcmlxxxiii

0

C'è una configurazione da utilizzare /auth/failure invece di sollevare una errore.

Io uso OmniAuth 1.2.2 e quando ho il controllo del FailureEndpoint ho trovato il codice è come this:

def call 
    raise_out! if OmniAuth.config.failure_raise_out_environments.include?(ENV['RACK_ENV'].to_s) 
    redirect_to_failure 
end 

E il failure_raise_out_environments è definito here:

def self.defaults 
    @defaults ||= { 
    # other configurations 
    :failure_raise_out_environments => ['development'] 
    } 
end 

L'ambiente può essere configurato quindi la soluzione è facile. Io uso Rails così ho messo sotto il codice in un file di inizializzazione:

OmniAuth.configure do |config| 
    # Always use /auth/failure in any environment 
    config.failure_raise_out_environments = [] 
end 
Problemi correlati