2011-05-26 15 views
7

Sto eseguendo Devise 1.3.4 con le rotaie 3.0.7. Ho due possibilità per gli utenti di accedere: utilizzando l'app Web e utilizzando un'app Web mobile (tramite una chiamata API JSON). Il primo modo è gestito perfettamente dal controller predefinito delle sessioni di sviluppo. Il metodo di autenticazione delle chiamate API deve trovarsi in un controller che estenda il mio Api::BaseController. Così, ho scritto questo secondo controller in questo modo:Devise: Più controllori gestiscono le sessioni utente

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 

tentativi di login tramite questo metodo non riescono a causa del metodo valid_controller? in Devise::Strategies::Authenticatable. Poiché ho lasciato il controller predefinito (devise/sessions) come controller mappato per gli utenti, non consente l'autenticazione dal mio controller personalizzato.

vorrei rotolare il mio funzionalità personalizzate nel mio sottoclasse di Devise::SessionsController, ma ho bisogno di il controller sessioni API per estendere la API::BaseController, quindi non posso estendere Devise::SessionsController pure. Non voglio posizionare i metodi di autenticazione delle applicazioni Web di comportamento predefiniti nel controller API, soprattutto perché ciò richiederebbe la copia dal controller di elaborazione.

Qualche suggerimento? C'è qualche configurazione che mi manca che permetta a più controller di gestire le sessioni? il metodo valid_controller? fa un confronto ==, non .include?, quindi non vedo come funzionerebbe.

UPDATE

Si tratta di una soluzione temporanea terribile. Non mi piace, quindi non sto postandolo come risposta, ma ho pensato che potesse offrire una riflessione a tutti i tipi di rispondenti:

Nella parte superiore del mio metodo di creazione, ho potuto scavalca ciò che Devise si aspetta di essere il controller delle sessioni.

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

Questo è il lavoro intorno funzionalità prevista di Devise (che richiede un singolo, un controller specifico per fare la creazione della sessione) in modo da non voglio tenerlo. Mi chiedo se questo vincolo sia una misura di sicurezza o solo una convenzione - se è per la sicurezza, questo è presumibilmente piuttosto brutto.

risposta

1

Posso solo suggerire un'altra soluzione (forse meno terribile?) In un inizializzatore è possibile sovrascrivere #valid_controller ?, come questo:

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

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

Sarei interessato a conoscere la ragione di questo vincolo troppo

+0

Questa è una buona idea. Sicuramente meno grave del mio. Stavo pensando di applicare patch per fare un '.include?' In 'valid_controller' e fornire un array nella mia dichiarazione di route. – andrewmitchell

0

Sto utilizzando Devise 2.2.7 con Rails 3.2.13. Entrambi i metodi precedenti non hanno funzionato per me: il metodo valid_vontroller? in Devise::Strategies::DatabaseAuthenticatable non esiste più. Il trucco Devise.mappings[:user].controllers[:sessions] non ha funzionato neanche per me.

Dopo aver scavato attraverso this thread ho trovato valid_params_request? che è responsabile per garantire che la richiesta deve essere inviata tramite il sistema di autenticazione. Esiste un metodo di supporto, allows_params_authentication!, che abilita lo Devise::SessionsController a elaborare le richieste di autenticazione.

È possibile autenticare un utente da qualsiasi controller:

def signin 
    allow_params_authentication! 
    authenticate_user! 
end 

Se si desidera reindirizzare a una pagina personalizzata quando l'autenticazione non riesce:

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

mi sono imbattuto la necessità di gestire l'autenticazione esterna una sottoclasse di Devise::SessionsController sviluppando un motore che funziona insieme a Spree Commerce, che già implementa l'autenticazione di creazione.

Problemi correlati