2011-11-17 15 views
6

Ho un'app per rails che fa una chiamata a api web, l'app rails da sola non ha alcun database o archivio utenti. Ogni chiamata API deve essere inviata nome utente e password per ogni richiesta.che memorizzano la password in una sessione

Vorrei fornire un meccanismo di autenticazione per l'app per i binari. Sto progettando di fare in questo modo:

  1. mostrare una pagina di login
  2. Prendi il nome utente e la password
  3. Conservare il nome utente e la password
  4. eseguire un'autenticazione manuale o tramite warden.authenticate o Authlogic Qualcosa (o potrebbe anche non essere richiesto può solo verificare se la sessione ha qualcosa memorizzato)
  5. E poi quando l'utente fa qualcosa passo il nome utente e la password che è stata memorizzata in precedenza.

Ora il mio problema è dove memorizzo la password? Se uso la sessione non posso usare ovviamente il cookie store, posso usare session_store = :active_record_store ma non sono sicuro che sia sicuro, inoltre non ho alcun database al momento, quindi perché dovrei crearne uno solo per la sessione? C'è qualche altro meccanismo per memorizzare le password all'interno di una sessione? (Modo sicuro, ovviamente)

rotaie prima era:

  • MemoryStore
  • FileStore

Ma ora entrambi sembra essere rimosso. Quindi qualsiasi altra soluzione?

Note di risposte:

  1. Memorizzazione di password criptate non funziona da quando ho bisogno della password grezza da inviare al server, mentre le chiamate API.
  2. Non ho alcun controllo sull'API, quindi non posso cambiare la sua autenticazione.
  3. Non c'è manutenzione del profilo utente sull'app per rails. Tutto gestito da chiamate API.

Alla fine ho pensato di implementare l'archivio di memoria personalizzato ma sembra che venga generato un errore di stackoverflow. Ho ottenuto il codice https://rails.lighthouseapp.com/projects/8994/tickets/1876-uninitialized-constant-actioncontrollersessionmemorystore

require 'action_dispatch' 
module ActionDispatch 
module Session 
class CustomMemoryStore < ActionDispatch::Session::AbstractStore 
    GLOBAL_HASH_TABLE = {} #:nodoc: 

    private 
    def get_session(env, sid) 
     sid ||= generate_sid 
     session = GLOBAL_HASH_TABLE[sid] || {} 
     session = AbstractStore::SessionHash.new(self, env).merge(session) 
     [sid, session] 
    end 

    def set_session(env, sid, session_data) 
     GLOBAL_HASH_TABLE[sid] = session_data 
     return true 
    end 
    end 
end 
end 
Steptools3::Application.config.session_store :custom_memory_store, :key => '_some_xyz' 
+0

È possibile memorizzare una password crittografata in un cookie o archiviare la sessione sul lato server nel DB. –

+0

Non è chiaro chi deve effettuare il login, in quale applicazione. Il railsapp (senza il db?). E un'altra app ha un'API?È roba webapi sotto il tuo controllo? Per rinviare l'autorizzazione a un'API, in genere utilizzerai OAuth (per non dover mantenere l'utente/password): consente all'utente di accedere all'altra applicazione e riceverai un token che ti concederà l'accesso temporaneo. – nathanvda

+0

l'utente della mia app inserisce nome utente e password, l'app rails chiama l'API, dice "dosomething", chiama "user: asd, passa: qwe, task: dosomething". non esiste quindi alcuna autenticazione tra l'app per rails e l'API ... è solo che devo passare il nome utente e la password su ogni richiesta. –

risposta

2

Si potrebbe provare a utilizzare Redis come un negozio di sessione. Usiamo la gemma rails3-redis-session-store. La fonte può essere trovata here.

È molto semplice da configurare e le sessioni scadono automaticamente, il che la rende sicura. Esempio config:

YourApp::Application.config.session_store :redis_session_store, 
              :db => 0, 
              :expire_after => 10.minutes, 
              :key_prefix => "your_app:session:" 

Un'alternativa sarebbe quella di utilizzare dalli, e quindi utilizzare memcached come terminali.

Spero che questo aiuti.

+0

non richiede la creazione di un database stesso? –

+0

Redis è un archivio di valori-chiave open-source. Devi infatti eseguirlo sul tuo server. Potresti anche usare memcached. Ma ancora una volta, questo sarà un processo che devi avviare sul tuo server. – nathanvda

+0

cool sembra una buona opzione ... Mantiene tutto in memoria e lo scrive di nuovo su disco dopo un po 'di tempo sembra una buona soluzione, ma un po' più di uccisione solo per memorizzare un valore in sessione. Cercherò di implementare custommemcache (risposta modificata) se non implementerà il tuo metodo. Grazie –

1

Consiglio di prendere il passo successivo e la creazione di una base di dati semplice e risparmiare un sacco di problemi per se stessi e l'utente, che cosa accade quando l'utente vuole tornare al sito, dovranno registrarsi nuovamente.

Trovo che lo Devise sia eccezionale per questo scopo e molto semplice da integrare.

Se c'è un problema in cui non si vuole avere un server di database classica esecuzione si consiglia di guardare MongoDB

+0

Non c'è alcuna registrazione .. L'utente viene creato tramite API e gestito tramite l'app api ... rails non fa tutto questo. –

1

I cookies di sessione vengono crittografati utilizzando la chiave di sessione. I tuoi dati dovrebbero essere sicuri finché tieni la chiave della sessione forte (128 caratteri) e sicura.

ActionController::Base.session = { 
    :key   => '_foo_bar_session', 
    :http_only => true, 
    :secret  => 'dldkdke420934indsknknkfsnh318u84e9u49832dfkdsajdsk' 
} 

Se si desidera memorizzare i dettagli di autenticazione oltre una sessione del browser, è possibile memorizzarli in cookie permanenti firmati.

cookies.permanent.signed[:user_credentials] = [login, password] 

I cookie firmati sono accessibili come i biscotti normali:

cookies[:user_credentials] 

assicurarsi di impostare una forte cookie_verifier_secret nel file di inizializzazione.

ActionController::Base.cookie_verifier_secret ='dskjkjfdshfddsfkhkr3898398430943' 

Riferimento

Signed and Permanent cookies in Rails 3

+0

Sto cercando di utilizzare questo: https://rails.lighthouseapp.com/projects/8994/tickets/1876-uninitialized-constant-actioncontrollersessionmemorystore. Ma sto ricevendo errore di overflow dello stack. qualcosa di simile a questo 'modulo ActionDispatch modulo Sessione classe CustomMemoryStore

+0

@GauravShah Stai tentando di utilizzare i cookie firmati oi cookie di sessione? I cookie di sessione sono firmati per impostazione predefinita. Quindi puoi usarli se non devi mantenere le credenziali oltre una sessione del browser. –

+0

@GauravShah Qual è la versione della tua rotaia? Stai usando il negozio di sessione di cookie? (Il messaggio di errore indica che si sta utilizzando il MemoryStore.) –

1

cercherò di analisi le vostre scelte:

Se Server è inciso con CustomMemoryStore

Si consideri il seguente scenario:

  • 4 Utenti A, B, C, D si registra
  • Il server è stato violato. L'hacker ottiene il controllo del server.
  • D ha fatto qualche operazione.
  • Hai scoperto che il tuo server è compromesso e hai riparato il tuo sistema.

Con CustomMemoryStore, l'hacker può ottenere le password di tutti gli utenti. Non è troppo difficile inserire una logica nell'esecuzione del processo Rails, o scaricare la memoria e l'analisi. Memorizzare la password in ActiveRecord, MongoDB, Redis ha problemi simili.

Se il server è compromesso con CookieStore?

Cosa succede se si verifica lo scenario precedente e si sta utilizzando CookieStore?

Rivediamo il meccanismo di CookieStore:

  • Server dispone di una chiave segreta per firmare & verificare sessione.
  • Ogni volta che il browser invia una richiesta, il server decrittografa la sessione, modifica i dati, firma la sessione e invia la sessione al browser nel cookie.

In altre parole, l'hacker non può ottenere la password dal cookie o dalla chiave segreta. Ha bisogno sia di cookie che di chiave segreta per rubare la password.

In questo scenario, le password di A, B, C sono sicure. Solo la password di D verrà rubata da Hacker. È possibile ridurre al minimo il danno riparando il sistema al più presto.

Il problema della CustomMemoryStore

Oltre al problema della sicurezza, so che siete a conoscenza di che CustomMemoryStore non è scalabile. Tuttavia, il problema potrebbe essere più grande di quanto pensi. Invierai la richiesta ad altri servizi web nell'azione del tuo controller, bloccherà l'intero server se il servizio remoto è lento o inattivo. Potrebbe essere doloroso anche se hai solo 1 ~ 10 utenti simultanei.

Anche se si decide di eseguire l'applicazione su un singolo server, è possibile avviare il processo di più binari con Passenger o Unicorn. CustomMemoryStore nega queste opzioni.

Preoccupazione Client Security

Se la preoccupazione è che se cookie viene rubata da un lato del browser, si può considerare EncryptedCookieStore. Cripta la sessione e memorizza nel cookie client. Non puoi ottenere la password se hai solo cookie o la chiave. È necessario sia il cookie che la chiave per decrittografare la password.

Qual è il problema chiave?

EncryptedCookieStore è più sicuro perché memorizza la password crittografata nel cookie dell'utente e la chiave segreta è disponibile solo sul server. L'hacker non può ottenere la password se ha solo il cookie o la chiave segreta - Ha bisogno di entrambi.

Naturalmente, è possibile implementare una logica simile con CustomMemoryStore. Ad esempio, memorizzare la password crittografata nella memoria del server e la chiave individuale si trova nel cookie. Se si decide ancora di memorizzare la password crittografata sul server, si consiglia di utilizzare Redis per l'archiviazione. È semplice e veloce rispetto a MySQL e MongoDB. CustomMemoryStore non è consigliato a causa di problemi di ridimensionamento.

Altri suggerimenti

password di un altro sistema è dati molto sensibili, si dovrebbe essere molto attenti a che fare con il problema della sicurezza. Se si tratta di un servizio pubblico, dovresti scrivere molto attentamente il tuo termine di servizio e il contratto di responsabilità. Inoltre, dovresti eseguire i tuoi servizi con HTTPS.

TL; DR

  • Usa OAuth se è possibile (Beh, so che non si può)
  • EncryptedCookieStore deve essere semplice e sicuro.
  • Se si decide di memorizzare la password sul server, si prega di crittografarlo e memorizzare la chiave segreta sul lato client (cookie).
+0

Non posso usare OAuth poiché API non è sotto il mio controllo. Prenderò in considerazione ciò che hai menzionato. Anche se non sono convinto della sicurezza del cookie lato client .. –

+0

Mi dispiace che ci sia qualche errore nella mia risposta precedente. Risolto il problema e aggiunta la sezione "Client Security Concern". – miaout17

+0

Aggiornato di nuovo la mia conclusione. – miaout17

Problemi correlati