2009-02-13 8 views
151

Disclaimer: Sono nuovo della scuola di pensiero REST, e sto cercando di avvolgere la mia mente intorno ad esso.Puoi aiutarmi a capire questo? "Errori comuni REST: le sessioni sono irrilevanti"

Quindi, sto leggendo questa pagina, Common REST Mistakes, e ho trovato che sono completamente sconcertato dalla sezione sulle sessioni che è irrilevante. Questo è quello che dice la pagina:

Non ci dovrebbe essere bisogno di un client per "accedere" o "avviare una connessione". L'autenticazione HTTP viene eseguita automaticamente per ogni messaggio. Le applicazioni client sono utenti delle risorse , non dei servizi. Pertanto, non c'è niente a cui accedere! Diciamo che stai prenotando un volo su un servizio web REST . Non si crea una nuova connessione "sessione" al servizio . Piuttosto, chiedi "itinerario oggetto creatore" per creare un nuovo itinerario . È possibile iniziare a riempire gli spazi vuoti, ma poi ottenere alcuni componenti totalmente altrove sul Web per riempire altri spazi vuoti. Non c'è nessuna sessione, quindi non c'è il problema della migrazione dello stato di sessione tra client. Non è inoltre disponibile il problema di "affinità di sessione" nel server (sebbene continui a caricare i problemi di bilanciamento per continuare).

OK, ho capito che l'autenticazione HTTP viene eseguita automaticamente su ogni messaggio, ma come? Il nome utente/la password sono inviati ad ogni richiesta? Non basta aumentare la superficie di attacco? Mi sento come se mi mancasse una parte del puzzle.

Sarebbe male avere un servizio REST, ad esempio /session, che accetta una richiesta GET, in cui si passerà un nome utente/password come parte della richiesta e si restituisce un token di sessione se l'autenticazione è avvenuta con successo , che potrebbe essere poi passato insieme alle richieste successive? Questo ha senso da un punto di vista REST, o è che manca il punto?

risposta

76

Per essere RESTful, ciascuna richiesta HTTP deve contenere sufficienti informazioni da sola per consentire al destinatario di elaborarla in completa armonia con la natura senza stato di HTTP.

Va bene, ottengo che l'autenticazione HTTP avviene automaticamente su ogni messaggio - ma come?

Sì, il nome utente e la password vengono inviati ad ogni richiesta. I metodi comuni per farlo sono autenticazione di accesso di base e autenticazione di accesso digest. E sì, un intercettatore può catturare le credenziali dell'utente. Si codificherebbe quindi tutti i dati inviati e ricevuti utilizzando Transport Layer Security (TLS).

sarebbe male avere un servizio REST , diciamo,/sessione, che accetta una richiesta GET , dove ci si passa in un username/password come parte della richiesta , e restituisce un token di sessione se l'autenticazione è avvenuta con successo, che può essere quindi inoltrata insieme alle richieste successive ? Questo rende la sensazione da un punto di vista REST o è che manca il punto?

Questo non sarebbe RESTful poiché comporta stato, ma è comunque abbastanza comune in quanto è una comodità per gli utenti; un utente non deve accedere ogni volta.

Quello che si descrive in un "token di sessione" viene comunemente definito come un cookie di accesso . Ad esempio, se provi ad accedere al tuo account Yahoo! account c'è una casella di controllo che dice "tienimi loggato per 2 settimane". Questo essenzialmente sta dicendo (nelle tue parole) "mantieni vivo il mio token di sessione per 2 settimane se effettuo il login con successo." I browser Web invieranno tali cookie di accesso (e possibilmente altri) con ogni richiesta HTTP che gli chiedi di fare per te.

+5

Questa risposta non ha senso per me. In primo luogo, dice che è OK passare l'accesso e la password ogni volta e quindi anche una volta, il che ha senso. Quindi, viene suggerita l'idea di restituire al client lo stato di accesso corretto sotto forma di token. Se necessario, il token potrebbe codificare l'ora della creazione. Siamo certamente autorizzati a restituire le informazioni al cliente. Quindi, questo suggerimento mi sembra soddisfacente. La risposta dice che non va bene perché "porta lo stato", ma non è l'idea di "ST" in "REST" che lo stato può essere trasferito tra il client e il server? –

31

Non è raro che un servizio REST richieda l'autenticazione per ogni richiesta HTTP. Ad esempio, Amazon S3 richiede che ogni richiesta abbia una firma derivata dalle credenziali dell'utente, dalla richiesta esatta da eseguire e dall'ora corrente. Questa firma è facile da calcolare sul lato client, può essere rapidamente verificata dal server ed è di uso limitato a un utente malintenzionato che la intercetta (poiché si basa sull'ora corrente).

+0

Amo questo approccio. Inizierà a usarlo subito –

+3

+1 puoi approfondire: _è di uso limitato a un utente malintenzionato che lo intercetta (poiché si basa sull'ora corrente) _? non stai parlando di un cookie che contiene nome utente e password criptati? come fa SO? (IMHO) –

+1

@RoyiNamir: Non sto parlando di un cookie. La firma utilizzata da S3 è un parametro della richiesta HTTP, ma * non * è un cookie, viene ricalcolata per ogni richiesta. –

3

Penso che il tuo suggerimento sia OK, se vuoi controllare la durata della sessione del client. Penso che l'architettura RESTful ti incoraggia a sviluppare applicazioni apolidi. Come @ 2pence ha scritto "ogni richiesta HTTP dovrebbe portare abbastanza informazioni da sola affinché il destinatario possa elaborarla in completa armonia con la natura stateless di HTTP".

Tuttavia, non sempre questo è il caso, a volte l'applicazione deve indicare quando il client esegue l'accesso o il logout e per mantenere le risorse come blocchi o licenze in base a queste informazioni. Vedere il mio follow-up question per un esempio di tale caso.

5

Va bene, ottengo che l'autenticazione HTTP avviene automaticamente su ogni messaggio - ma come?

"Autorizzazione:" intestazione HTTP inviata dal client. O semplice (testo normale) o digest.

sarebbe male avere un servizio REST , diciamo,/sessione, che accetta una richiesta GET , dove ci si passa in un username/password come parte della richiesta , e restituisce un token di sessione se l'autenticazione è avvenuta con successo, che può essere quindi inoltrata insieme alle richieste successive ? Questo rende la sensazione da un punto di vista REST o è che manca il punto?

L'intera idea della sessione è quello di rendere stateful applicazioni che utilizzano il protocollo stateless (HTTP) e il client muto (browser web), mantenendo lo stato sul lato server. Uno dei principi REST è "Ogni risorsa è indirizzabile in modo univoco utilizzando una sintassi universale da utilizzare nei collegamenti ipermediali". Le variabili di sessione sono qualcosa a cui non è possibile accedere tramite URI. L'applicazione veramente RESTful manterrebbe lo stato dal lato del cliente, inviando tutte le variabili necessarie tramite HTTP, preferibilmente nell'URI.

Esempio: ricerca con impaginazione. Avresti URL in forma

http://server/search/urlencoded-search-terms/page_num 

E 'ha molto in comune con URL segnalibro

+4

Le informazioni di autenticazione non sono accessibili tramite URI, tuttavia: tutti stanno parlando dell'invio di informazioni di autorizzazione come parte dell'intestazione della richiesta. In che modo è diverso dall'includere un token di sessione con la richiesta? Non sto dicendo di usare il token di sessione nell'URI, ma nei dati passati nella richiesta. –

+0

L'autenticazione stabilisce se si è autorizzati a eseguire tale azione e in un'applicazione RESTful non influirà sul risultato. – vartec

+4

Un token di sessione stabilisce anche se sei autorizzato ad eseguire tale azione. Cosa vuoi dire che non influenzerebbe il risultato? Se il chiamante non è autorizzato, riceve un errore Non autorizzato. Stessa cosa con un token di sessione. Davvero non vedo la differenza? –

8

No, non manca il punto. Lo ClientLogin di Google funziona esattamente in questo modo con l'eccezione degna di nota che al client viene richiesto di passare alla "/ sessione" utilizzando una risposta HTTP 401. Ma questo non crea una sessione, crea solo un modo per i client di autenticarsi (temporaneamente) senza passare le credenziali in chiaro e per il server controllare la validità di queste credenziali temporanee come meglio crede.

+0

Tuttavia, ciò non sembra RESTful. –

+11

@ unforgiven3 Fintanto che il token restituito viene utilizzato solo per autenticare l'utente e non utilizzato dal server per associare l'utente ad altro stato memorizzato sul server, non vedo violazioni REST. –

+0

@Darrel, come potrebbero essere autenticate le successive richieste HTTP? La mia comprensione è che l'autenticazione avviene su ogni richiesta HTTP. –

10

Molte persone non capiscono i principi REST molto chiaramente, l'uso di un token di sessione non significa sempre che si è dichiarati, il motivo per inviare nome utente/password con ogni richiesta è solo per l'autenticazione e lo stesso per l'invio di un token (generato dal processo di login) solo per decidere se il cliente ha il permesso di richiedere o meno dati, si viola solo le convinzioni di REST quando si utilizzano noi stessi username/password o token di sessione per decidere quali dati mostrare! invece devi usarli solo per l'autenticazione (per mostrare o non mostrare i dati)

nel tuo caso dico SI questo è RESTy, ma cerca di evitare l'utilizzo di sessioni PHP native nella tua API REST e inizia a generare il tuo gettoni hash che scadono in determinati periodi di tempo!

+0

grazie. perché si dovrebbe evitare la sessione nativa di php e usare invece i propri token hash? – Matthew

+0

non c'è una ragione geniale che dico, solo per maggiore sicurezza e maggiore controllo. – EvilThinker

+0

Questo è migliore della risposta accettata. Come minimo, accetta il suggerimento come RESTy, che ha senso. Tuttavia, non vedo perché le informazioni passate non possano essere utilizzate per fare un'autorizzazione dipendente dall'utente. Alcuni utenti potrebbero avere accesso ad alcuni dati e altri no. Ciò non rende il protocollo non RESTful. –