2011-05-26 13 views
7

Estoy ejecutando el dispositivo 1.3.4 con rieles 3.0.7. Tengo dos maneras en que los usuarios pueden iniciar sesión: usar la aplicación web y usar una aplicación web móvil (a través de una llamada API JSON). La primera forma se maneja perfectamente con el controlador predeterminado de sesiones de diseño. El método de autenticación de llamada de API debe estar en un controlador que extienda mi Api::BaseController. Por lo tanto, he escrito este segundo controlador de la siguiente manera:Idear: Tener varios controladores manejar sesiones de usuario

class Api::UserSessionsController < Api::BaseController 
    … 
    def create 
    user = warden.authenticate(:scope => :user) 
    if user 
     sign_in(:user, user) 
    else 
     # Do some error handling 
    end 
    end 
end 

Los intentos de inicio de sesión mediante este método fallan debido al método valid_controller? en Devise::Strategies::Authenticatable. Debido a que he dejado el controlador predeterminado (devise/sessions) como el controlador asignado para los usuarios, no permite las autenticaciones desde mi controlador personalizado.

me gustaría rodar mi funcionalidad personalizada en mi propia subclase de Devise::SessionsController, pero necesita el controlador de sesiones de API para ampliar el API::BaseController, así que no puedo extender Devise::SessionsController también. No quiero ubicar los métodos de autenticación de la aplicación web de comportamiento predeterminado en el controlador API, especialmente porque esto requeriría copiarlos del controlador de diseño.

¿Alguna sugerencia? ¿Hay alguna configuración que me falta que permita que varios controladores manejen sesiones? el método valid_controller? hace una comparación ==, no .include?, así que no veo cómo funcionaría eso.

ACTUALIZACIÓN

Ésta es una solución temporal horrible. No me gusta, así que no lo publico como una respuesta, pero pensé que podría ofrecer algo de reflexión para todos sus tipos de contestador:

En la parte superior de mi método de creación, podría anula lo que Devise espera sea el controlador de sesiones.

Devise.mappings[:user].controllers[:sessions] = params[:controller] 

Esto es trabajar en torno funcionalidad prevista de Concebir (que requiere un controlador único, específico para hacer creación de la sesión), así que no quieren mantenerlo. Me pregunto si esta restricción es una medida de seguridad o simplemente una convención; si se trata de seguridad, esto es presumiblemente bastante malo.

Respuesta

1

sólo puedo sugerir otra solución (tal vez menos horrible?) En un inicializador puede sobrescribir #valid_controller ?, así:

require 'devise/strategies/authenticatable' 
require 'devise/strategies/database_authenticatable' 

class Devise::Strategies::DatabaseAuthenticatable 
    def valid_controller? 
    # your logic here 
    true 
    end 
end 

estaría interesado en conocer la razón de esta limitación también

+0

Esa es una muy buena idea. Ciertamente menos burdo que el mío. Estaba pensando en arreglar el dispositivo para hacer un '.include?' En 'valid_controller' y suministrar una matriz en mi declaración de rutas. – andrewmitchell

0

Estoy usando Devise 2.2.7 con Rails 3.2.13. Ninguno de los dos métodos anteriores funcionó: el método valid_vontroller? en Devise::Strategies::DatabaseAuthenticatable ya no existe. El truco Devise.mappings[:user].controllers[:sessions] tampoco funcionó para mí.

Después de buscar en this thread Encontré valid_params_request? que es responsable de garantizar que la solicitud se envíe a través del sistema de autenticación. Hay un método de ayuda, allows_params_authentication!, que es lo que habilita el Devise::SessionsController para procesar solicitudes de autenticación.

Puede autenticar un usuario desde cualquier controlador por:

def signin 
    allow_params_authentication! 
    authenticate_user! 
end 

Si desea redirigir a una página personalizada cuando falla la autenticación:

resource = warden.authenticate!({ 
    :scope => :user, 
    :recall => "#{controller_path}#login" 
}) 
sign_in(:user, resource) 

me encontré con la necesidad de una gestión de la autenticación fuera una subclase de Devise::SessionsController mediante el desarrollo de un motor que funciona junto con Spree Commerce, que ya implementa la autenticación del dispositivo.

Cuestiones relacionadas