2012-04-06 6 views
19

Uso l'autenticate_utente del dispositivo! metodo in un controller. Questo funziona bene quando l'auth_token previsto nella richiesta è quella giusta, ma se l'autenticazione non riesce, io alla fine con:Come rimuovere il reindirizzamento html in devise authenticate_user

curl -XGET 'http://localhost:3000/my_obj?auth_token=wrongtoken' 

<html><body>You are being <a href="http://localhost:3000/users/sign_in">redirected</a>.</body></html> 

come io uso Rabl, qual è il modo migliore per avere qualcosa di simile

{'error' : 'authentication error'} 

restituito intead del reindirizzamento html?

risposta

41

lo faccio nel evitano il filtro con: format =>: risposta JSON e fare il mio proprio filtro per rendere la mia risposta JSON, se non passa current_user

class MyController < ApplicationController 
    before_filter :authenticate_user!, :unless => { request.format == :json } 
    before_filter :user_needed, :if => { request.format == :json } 

    def user_needed 
    unless current_user 
     render :json => {'error' => 'authentication error'}, :status => 401 
    end 
    end 
end 

Un altro modo, può essere più pulito è quello di definire il proprio FailureApp (https://github.com/plataformatec/devise/blob/master/lib/devise/failure_app.rb)

class MyFailureApp < Devise::FailureApp 
    def respond 
    if request.format == :json 
     json_failure 
    else 
     super 
    end 
    end 

    def json_failure 
    self.status = 401 
    self.content_type = 'application/json' 
    self.response_body = "{'error' : 'authentication error'}" 
    end 
end 

Nel Devise file di configurazione aggiuntivo:

config.warden do |manager| 
    manager.failure_app = MyFailureApp 
end 
+0

Ho provato il secondo approccio per evitare di dover ripetere lo stesso codice in tutti i miei controller. Ho creato la classe MyFailureApp in lib/failure.rb e ho cambiato la configurazione. Però non riesco a farlo funzionare, ottengo il '!! Errore imprevisto durante l'elaborazione della richiesta: costante non inizializzata MyFailureApp '. Qualche idea sul perché questo ragazzo non venga caricato? – Luc

+0

È necessario richiedere che il file richieda l''errore' nella parte superiore della configurazione di Devise – shingara

+0

(stupido) Ottimo, funziona correttamente. Grazie. – Luc

32

Nelle versioni più recenti di escogitare (sto usando 2.2.0), è possibile utilizzare l'opzione navigational_formats nel file di configurazione Devise, devise.rb:

# ==> Navigation configuration 
# Lists the formats that should be treated as navigational. Formats like 
# :html, should redirect to the sign in page when the user does not have 
# access, but formats like :xml or :json, should return 401. 
# 
# If you have any extra navigational formats, like :iphone or :mobile, you 
# should add them to the navigational formats lists. 
# 
# The "*/*" below is required to match Internet Explorer requests. 
config.navigational_formats = ["*/*", :html] 

Finché :json non è in quella lista, e la vostra richiesta termina in .json, si comporterà come si desidera.

+2

Questo mi ha fatto risparmiare un'incredibile quantità di tempo, grazie! –

+0

Sono rimasto sconcertato tutto il giorno fino a quando ho visto il tuo punto sulla richiesta che termina con .json. Bello spettacolo, bello spettacolo –

+2

Aggiungi 'application/json' a' Headers' della richiesta e non hai bisogno di '.json' alla fine dell'URL. – rmagnum2002