Questa domanda è stata affrontata, in una forma leggermente diversa, a lungo, qui:
Autenticazione RESTful
Ma questo si rivolge dal lato server. Diamo un'occhiata a questo dal lato client. Prima di farlo, però, c'è un preludio importante:
Javascript Crypto è senza speranza
L'articolo di Matasano su questo è famoso, ma le lezioni in esso contenute sono piuttosto importanti:
https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/
Riassumere:
- Un attacco man-in-the-middle può sostituire banalmente il tuo codice crittografico con
<script>
function hash_algorithm(password){ lol_nope_send_it_to_me_instead(password); }</script>
- Un attacco man-in-the-middle è banale contro una pagina che serve qualsiasi risorsa tramite una connessione non SSL.
- Una volta che hai SSL, stai usando la vera crittografia comunque.
E per aggiungere un mio corollario:
- Un attacco XSS riuscito può comportare l'esecuzione di codice da parte di un utente malintenzionato nel browser del client, anche se si utilizza SSL, quindi anche se si dispone di ogni tratteggio abbattuto, la crittografia del browser può comunque fallire se l'attaccante trova un modo per eseguire qualsiasi codice javascript sul browser di qualcun altro.
Ciò rende un sacco di schemi di autenticazione RESTful impossibili o sciocchi se si intende utilizzare un client JavaScript. Guardiamo!
HTTP Basic Auth
Innanzitutto, HTTP Basic Auth. Il più semplice degli schemi: passa semplicemente un nome e una password ad ogni richiesta.
Questo, ovviamente, richiede assolutamente SSL, perché stai passando un nome e una password con codifica Base64 (reversibilmente) ad ogni richiesta. Chiunque ascolta sulla linea potrebbe estrarre banalmente nome utente e password. La maggior parte degli argomenti "Basic Auth is insecure" provengono da un luogo di "Basic Auth over HTTP" che è una pessima idea.
Il browser fornisce il supporto HTTP Auth autenticato, ma è brutto come peccato e probabilmente non dovresti usarlo per la tua app. L'alternativa, tuttavia, è quella di nascondere nome utente e password in JavaScript.
Questa è la soluzione più RESTful. Il server non richiede alcuna conoscenza dello stato e autentica ogni singola interazione con l'utente. Alcuni appassionati di REST (per lo più uomini di paglia) insistono sul fatto che mantenere qualsiasi tipo di stato è un'eresia e si schiumerà alla bocca se si pensa a qualsiasi altro metodo di autenticazione. Ci sono vantaggi teorici in questo tipo di conformità agli standard - è supportato da Apache immediatamente - puoi memorizzare i tuoi oggetti come file in cartelle protette da file .htaccess se il tuo cuore lo desidera!
Il problema ? Stai memorizzando nella cache sul lato client un nome utente e una password. Questo dà a evil.ru una soluzione migliore - anche la più elementare delle vulnerabilità XSS potrebbe far sì che il client trasmetta il suo nome utente e password a un server malvagio. Puoi provare ad alleviare questo rischio eseguendo l'hashing e salando la password, ma ricorda: JavaScript Crypto è senza speranza . Potresti alleviare questo rischio lasciandolo al supporto Auth di base del Browser, ma ... brutto come peccato, come menzionato in precedenza.
HTTP Digest Auth
L'autenticazione Digest è possibile con jQuery?
Un'autenticazione più "sicura", questa è una sfida hash richiesta / risposta. Tranne JavaScript Crypto è senza speranza , quindi funziona solo su SSL e devi ancora memorizzare nella cache il nome utente e la password sul lato client, rendendolo più complicato di HTTP Basic Auth ma non più sicuro .
Autenticazione della query con parametri di firma aggiuntivi.
Un'altra autenticazione più "sicura", in cui si crittografano i parametri con dati nonce e timing (per proteggere da attacchi ripetuti e timing) e si invia il file. Uno dei migliori esempi di questo è il protocollo OAuth 1.0, che è, per quanto ne so, un modo piuttosto sbalorditivo per implementare l'autenticazione su un server REST.
http://tools.ietf.org/html/rfc5849
Oh, ma non ci sono client OAuth 1.0 per JavaScript. Perché?
JavaScript Crypto è senza speranza , ricorda. JavaScript non può partecipare a OAuth 1.0 senza SSL e devi ancora memorizzare il nome utente e la password del client localmente - il che lo pone nella stessa categoria di Digest Auth - è più complicato di HTTP Basic Auth ma non è più sicuro .
Gettone
L'utente invia un nome utente e una password e, in cambio, ottiene un token che può essere utilizzato per autenticare le richieste.
Questo è leggermente più sicuro di HTTP Basic Auth, perché una volta completata la transazione nome utente / password è possibile eliminare i dati sensibili. È anche meno RESTful, poiché i token costituiscono "stato" e rendono più complicata l'implementazione del server.
SSL ancora
Il problema però è che devi ancora inviare il nome utente e la password iniziali per ottenere un token. Le informazioni sensibili toccano ancora il tuo JavaScript compromettibile.
Per proteggere le credenziali del tuo utente, devi comunque tenere gli aggressori fuori dal tuo JavaScript e devi comunque inviare un nome utente e una password via cavo. SSL richiesto.
Scadenza token
È comune applicare politiche di token come "hey, quando questo token è in circolazione da troppo tempo, scartarlo e rendere nuovamente autentico l'utente". o "Sono abbastanza sicuro che l'unico indirizzo IP autorizzati a utilizzare questo token è XXX.XXX.XXX.XXX
". Molte di queste politiche sono idee piuttosto buone.
Firesheeping
Tuttavia, l'utilizzo di un token senza SSL è ancora vulnerabile a un attacco chiamato "sidejacking": http://codebutler.github.io/firesheep/
L'attaccante non ottiene le credenziali dell'utente, ma può ancora fingere di essere il tuo utente, il che può essere piuttosto negativo.
tl; dr: l'invio di token non crittografati sul cavo significa che gli aggressori possono facilmente prendere quei token e fingere di essere i tuoi utenti. FireSheep è un programma che lo rende molto semplice.
Una zona separata, più sicura
Più grande è l'applicazione in esecuzione, più difficile sarà assolutamente assicurarsi che non siano in grado di iniettare del codice che modifica il modo in cui elaborate i dati sensibili. Ti fidi assolutamente della tua CDN? I tuoi inserzionisti? La tua base di codice?
Comune per i dettagli della carta di credito e meno comune per nome utente e password: alcuni implementatori mantengono l'inserimento dei dati sensibili in una pagina separata dal resto della loro applicazione, una pagina che può essere strettamente controllata e bloccata il meglio possibile, preferibilmente una che è difficile phishing con gli utenti.
Cookie (significa solo token)
È possibile (e comune) inserire il token di autenticazione in un cookie. Questo non cambia nessuna delle proprietà di auth con il token, è più una cosa comoda. Tutti gli argomenti precedenti si applicano ancora.
Sessione (significa ancora solo token)
Session Auth è solo l'autenticazione con token, ma con alcune differenze che la fanno sembrare una cosa leggermente diversa:
- Gli utenti iniziano con un token non autenticato.
- Il back-end mantiene un oggetto "stato" collegato al token di un utente.
- Il token è fornito in un cookie.
- L'ambiente di applicazione estrae i dettagli da te.
A parte questo, però, non è diverso da Token Auth, davvero.
Questo si allontana ancora di più da un'implementazione RESTful - con gli oggetti di stato stai andando sempre più avanti lungo il percorso del semplice RPC su un server stateful.
OAuth 2.0
OAuth 2.0 esamina il problema di "In che modo il software A consente al software B di accedere ai dati dell'utente X senza che il software B abbia accesso alle credenziali di accesso dell'utente X".
L'implementazione è semplicemente un modo standard per un utente di ottenere un token, e quindi per un servizio di terze parti andare "sì, questo utente e questo token corrispondono, e ora puoi ottenere alcuni dei loro dati da noi".
Fondamentalmente, tuttavia, OAuth 2.0 è solo un protocollo token. Presenta le stesse proprietà di altri protocolli token - hai ancora bisogno di SSL per proteggere quei token - cambia solo il modo in cui questi token vengono generati.
Esistono due modi in cui OAuth 2.0 può aiutarti:
- Fornire autenticazione / informazioni ad altri
- Ottenere autenticazione / informazioni da altri
Ma quando si tratta di esso, stai solo ... usando i token.
Torna alla tua domanda
Pertanto, la domanda che mi stai ponendo è "devo archiviare il token in un cookie e fare in modo che la gestione automatica della sessione del mio ambiente si occupi dei dettagli o devo archiviare il token in Javascript e gestirli da solo?"
E la risposta è: fai tutto ciò che ti rende felice .
La cosa sulla gestione automatica delle sessioni, tuttavia, è che sta accadendo molta magia dietro le quinte per te. Spesso è più bello avere il controllo di quei dettagli da soli.
Ho 21 anni, quindi SSL è sì
L'altra risposta è: utilizzare https per tutto o i briganti ruberanno le password e i token degli utenti.