2014-09-14 11 views
7

Il problema che sto riscontrando è che sto utilizzando i custodi resource owner credential flow per autenticare un utente da un'app iOS. Il mio progetto ha due modelli utente separati (chiamiamoli Utente e Amministratore). Il mio codice è simile al seguente:Flusso credenziali del proprietario delle risorse di Doorkeeper per più modelli

resource_owner_from_credentials do |routes| 
    user = User.find_for_database_authentication(:email => params[:username]) 
    user if user && user.valid_password?(params[:password]) 
end 

Funziona, ma come faccio a controllare anche l'amministratore? In altre parole, non so se la persona che accede è un utente o un amministratore - come faccio a verificare per entrambi?

risposta

9

Doorkeeper fornisce Scopes per questo scopo (vedi https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes)

Quindi, nel file doorkeeper.rb si può fare:

resource_owner_from_credentials do |routes| 
    if params[:scope].present? 
    case params[:scope] 
     when "user" 
     u = User.find_for_database_authentication(:email => params[:email]) 
     when "admin" 
     u = Admin.find_for_database_authentication(:email => params[:email]) 
    end 
    else 
    #default auth 
    u = User.find_for_database_authentication(:email => params[:email]) 
    end 
    u if u && u.valid_password?(params[:password]) 
end 

Poi per l'autenticazione della risorsa (ex amministratore.) È possibile effettuare una richiesta del genere:

POST $HOST/oauth/token 
{ 
    email: [email protected] 
    password: johndoe 
    grant_type: password 
    scope: admin 
} 
+1

GRAZIE! Ho rinunciato a questo molto tempo fa ma oggi ho dovuto completare il progetto. Sono tornato qui con l'intenzione di pubblicare nuovamente questa domanda e ho trovato la tua risposta. Era esattamente quello che stavo cercando. GRAZIE! –

1

Si esegue questa operazione passando un parametro aggiuntivo e scegliendo il mo vuoi che si autentifichino in base a quel parametro. Questo è simile alla risposta di gdonato, ma gli scope in doorkeeper sono meglio usati per gestire quali permessi vengono dati all'app autenticata (ad esempio "Autorizza questa app a leggere X e scrivere Y per tuo conto").

Ecco quello che sto usando

resource_owner_from_credentials do |routes| 
    if params[:user_type].present? 
    case params[:user_type] 
    when 'user' 
     u = User.find_for_database_authentication(email: params[:email]) 
    when 'employer' 
     u = Employer.find_for_database_authentication(email: params[:email]) 
    when 'admin' 
     u = Administrator.find_for_database_authentication(email: params[:email]) 
    end 
    end # I don't want a default auth user_type, so no 'else' block for me 
    user if user && user.valid_password?(params[:password]) 
end 

Si noti che se si dovesse fare questo usando gli ambiti invece di un param che portinaio non sta già utilizzando per qualcos'altro, dovrete configurare gli ambiti come:

# These are found in doorkeeper.rb, but they're commented by default. 
# You would use whatever scopes you're wanting to check 
default_scopes :public 
optional_scopes :write, :update 

Usando portata come param di distinguere tra utente e amministratore potrebbe funzionare senza jiggering default_scopes o optional_scopes in doorkeeper.rb, ma solo come un effetto collaterale della scoping che portinaio si aspetta.