2012-04-06 25 views
19

Utilizo authenticate_user del dispositivo. método en un controlador. Esto funciona bien cuando el auth_token proporcionada en la solicitud es el correcto, pero si falla la autenticación, que termina con:Cómo eliminar la redirección html en idear 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> 

Como utilizo Rabl, ¿cuál es la mejor manera de tener algo como

{'error' : 'authentication error'} 

devuelto intead de la redirección html?

Respuesta

41

yo que en evitar el filtro con Formato =>: respuesta JSON y hacer mi propio filtro para rendir mi respuesta JSON si no se pase 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 

Una otra manera, puede ser más limpio es definir su propio 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 

En su Diseñar archivo de configuración add:

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

Probé la segunda aproximación para evitar tener que repetir el mismo código en todos mis controladores. Creé la clase MyFailureApp en lib/failure.rb y cambié la configuración. Sin embargo, no logro hacerlo funcionar, ¡¡¡¡¡¡¡¡¡¡¡¡¡¡!! Error inesperado al procesar la solicitud: constante no inicializada MyFailureApp '. ¿Alguna idea de por qué este tipo no se carga? – Luc

+0

Necesita que su archivo requiera 'falla' en su parte superior de la configuración de Devise – shingara

+0

(tonto) Genial, está funcionando bien. Gracias. – Luc

32

En las versiones más recientes del Legado (estoy usando 2.2.0), puede utilizar la opción navigational_formats en el archivo de configuración que concebir y 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] 

Mientras :json no está en esa lista, y su solicitud termina en .json, se comportará como lo desee.

+2

Esto me ahorró una increíble cantidad de tiempo, ¡gracias! –

+0

Estuve desconcertado todo el día hasta que vi su punto sobre la solicitud que termina en .json. Buen espectáculo, buen espectáculo. –

+2

Agregue 'application/json' a' Headers' de la solicitud y no necesita '.json' al final de la url. – rmagnum2002