22

Come posso eseguire l'override di current_user di devise gem. In realtà ho bisogno di aggiungere servizi web per mobile-app.Dove sovrascrivere il metodo helper current_user di devise gem

Attualmente concepisce la gestione di sessione e "utente corrente" per l'applicazione Web.

Ora l'applicazione mobile invierà user_id al server. Ho bisogno di sovrascrivere l'utente corrente come questo

def current_user 
    if params[:user_id].blank? 
    current_user 
    else 
    User.find(params[:user_id]) 
    end 
end 

Devo modificare Devise Gem come plugin? o qualcos'altro ?
Gentilmente spiegare in dettaglio come sono nuovo in rotaie.

Cordiali saluti,

+2

yikes ... quindi, stai dicendo quando un agente mobile invia un user_id ti basta fidarti? –

+0

anche una chiave segreta di autenticazione –

+0

Devise gestirà tale token_authenticatable - passando semplicemente authentication_token su, non c'è bisogno di user_id. –

risposta

46

a seconda del modulo Devise::Controllers::Helpers, current_user (insieme a tutti gli altri soccorritori testamentaria) viene aggiunto a ApplicationController, il che significa che è possibile ignorare in questo modo:

# in application_controller.rb 
alias_method :devise_current_user, :current_user 
def current_user 
    if params[:user_id].blank? 
    devise_current_user 
    else 
    User.find(params[:user_id]) 
    end 
end 
+8

Errore nella riga "alias_method": undefined_method 'current_user' per la classe ApplicationController (NameError), all'avvio del mio ambiente. Se commento, avvio e commento, funziona perfettamente. Hai una soluzione? – Frexuz

+5

Frexuz, prova a sostituire alias_method con qualcosa del tipo: def devise_current_user {@devise_current_user || = warden.authenticate (: scope =>: user)} –

+0

è un thread-safe? Sto ricevendo errori nul in punti strani nei controller dopo l'autenticazione su MRI. –

5

Il altra risposta che suggerisce l'aliasing del metodo non è in realtà la soluzione migliore. commento di Doug inglese è la soluzione migliore:

# In ApplicationHelper 
def devise_current_user 
    @devise_current_user ||= warden.authenticate(:scope => :user) 
end 

Ecco il motivo:

che tu abbia compreso il vostro ApplicationHelper nel controller. Se hai bisogno di un metodo nel tuo ApplicationHelper che si basa su devise_current_user, vista la soluzione alias all'interno del controller, sei sfortunato.

Ma con la definizione del metodo esplicito sopra, è possibile spostare la definizione sull'helper e chiamarla da altri metodi e si può ancora includerla nel controller.

Questo è utile, ad esempio, quando si sviluppa una soluzione di impersonificazione utente e si devono mostrare due diversi utenti nella vista, uno per l'amministratore reale (devise_current_user) e l'altro, l'utente rappresentato (current_user) .

+2

In effetti hai ragione. Si prega di ricordare che quanto segue dovrebbe essere incluso in 'ApplicationController': 'include ApplicationHelper'. Altrimenti, 'devise_current_user' diventa sconosciuto. –

0

Supponendo che possiamo fidarci dei nostri dati di sessione (che si basa sul fatto che si mette l'input dell'utente in là senza autorizzazione appropriata o no), questo potrebbe funzionare come una preoccupazione:

module Concerns 
    module ControllerWithImpersonation 
    extend ActiveSupport::Concern 

    included do 
     helper_method :devise_current_user 
    end 

    def current_user 
     if session[:impersonated_user_id].blank? 
     devise_current_user 
     else 
     User.find(session[:impersonated_user_id]) 
     end 
    end 

    def devise_current_user 
     @devise_current_user ||= warden.authenticate(:scope => :user) 
    end 

    end 
end 

sto usando questo in un progetto per ora.

Una domanda minore (nella risposta, mi spiace) ... dovrei essere a conoscenza di eventuali modifiche in Devise o Warden che rendono obsoleto lo devise_current_user obsoleto?

0

risposta di Limbo-Peng è grande, ma può essere migliorata un po 'per assicurarsi che solo gli amministratori possono fare questo:

Sarà necessario definire anche un metodo is_admin? o is_admin attributo della classe utente.

Si potrebbe anche voler utilizzare una chiave diversa da user_id, quindi non entrerà mai in conflitto con i parametri regolari.

# to impersonate another user, e.g. for customer support 
# only admins can do this.. 
# 
alias_method :devise_current_user, :current_user 
def current_user 
    if ! params[:user_id].blank? \ 
    && devise_current_user && devise_current_user.is_admin? 
    User.find(params[:user_id]) 
    else 
    devise_current_user 
    end 
end 
Problemi correlati