Potete aiutarmi a capirlo? "Errori comuni di REST: le sessioni sono irrilevanti"


159

Disclaimer: sono una novità per la scuola di pensiero REST e sto provando a pensarci su.

Quindi, sto leggendo questa pagina, Errori comuni di REST , e ho scoperto che sono completamente sconcertato dal fatto che la sezione sulle sessioni sia irrilevante. Questo è ciò che dice la pagina:

Non dovrebbe essere necessario un client per "accedere" o "avviare una connessione". L'autenticazione HTTP viene eseguita automaticamente su ogni messaggio. Le applicazioni client sono consumatori di risorse, non servizi. Pertanto non c'è nulla a cui accedere! Supponiamo che tu stia prenotando un volo su un servizio web REST. Non si crea una nuova connessione "sessione" al servizio. Piuttosto chiedi "all'oggetto creatore dell'itinerario" di crearti un nuovo itinerario. Puoi iniziare a riempire gli spazi vuoti ma poi ottenere qualche componente totalmente diverso altrove sul web per riempire alcuni spazi vuoti. Non esiste alcuna sessione, quindi non esiste alcun problema di migrazione dello stato della sessione tra client. Non vi è inoltre alcun problema di "affinità di sessione"

Va bene, ottengo che l'autenticazione HTTP viene eseguita automaticamente su ogni messaggio, ma come? Il nome utente / la password vengono inviati ad ogni richiesta? Questo non aumenta semplicemente la superficie di attacco? Mi sento come se mi mancasse una parte del puzzle.

Sarebbe male avere un servizio REST, per esempio, /sessionche accetti una richiesta GET, in cui si passerebbe un nome utente / password come parte della richiesta e restituisca un token di sessione se l'autenticazione ha esito positivo, che potrebbe essere quindi passato con successive richieste? Ha senso dal punto di vista del RESTO o manca il punto?


ogni richiesta è sempre autenticata, il dirottamento di sessione è una cosa. riposante rende questo più ovvio ma non più esposto.
Jasen,

Risposte:


79

Per essere RESTful, ogni richiesta HTTP dovrebbe contenere informazioni sufficienti da sola affinché il suo destinatario le elabori in completa armonia con la natura apolide dell'HTTP.

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

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

Sarebbe male avere un servizio REST, diciamo, / session, che accetta una richiesta GET, in cui si passerebbe un nome utente / password come parte della richiesta e restituisce un token di sessione se l'autenticazione ha esito positivo, che potrebbe essere poi passato insieme alle successive richieste? Ha senso dal punto di vista del RESTO o manca il punto?

Questo non sarebbe RESTful poiché porta lo stato ma è comunque abbastanza comune poiché è una comodità per gli utenti; un utente non deve effettuare il login ogni volta.

Quello che descrivi in ​​un "token di sessione" viene comunemente chiamato a cookie di accesso . Ad esempio, se provi ad accedere al tuo account Yahoo! Nell'account è presente una casella di controllo che dice "Resta connesso per 2 settimane". Questo significa essenzialmente (con le tue parole) "mantenere attivo il token di sessione per 2 settimane se eseguo l'accesso correttamente". 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. Innanzitutto, dice che è OK passare il login 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 il tempo di creazione. Siamo certamente autorizzati a restituire informazioni al cliente. Quindi, questo suggerimento mi sembra perfetto. La risposta dice che non va bene perché "porta stato", ma l'idea di "ST" in "REST" non può essere trasferita tra il client e il server?

33

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, la richiesta esatta da eseguire e l'ora corrente. Questa firma è facile da calcolare sul lato client, può essere rapidamente verificata dal server ed è di utilità limitata per un utente malintenzionato che la intercetta (poiché si basa sull'ora corrente).


3
+1 puoi per favore approfondire: è di utilità limitata per un attaccante che lo intercetta (poiché si basa sull'ora corrente) ? non stai parlando di un cookie che contiene nome utente e password crittografati? come fa SO? (IMHO)
Royi Namir,

2
@RoyiNamir: non sto parlando di un cookie. La firma utilizzata da S3 è un parametro per la richiesta HTTP, ma non è un cookie, viene ricalcolata per ogni richiesta.
Greg Hewgill

Quindi, se devo salvare alcune informazioni su un utente, dove dovrei salvarle? in db? Non voglio andare ogni richiesta a db .... e comunque voglio usare il resto .... puoi aiutarmi per favore?
Royi Namir,

@RoyiNamir: se hai domande specifiche su come raggiungere qualche obiettivo, per favore fai una nuova domanda . Non posso rispondere ad altre domande qui nei commenti.
Greg Hewgill

10

Molte persone non capiscono i principi REST in modo molto chiaro, l'utilizzo di un token di sessione non significa sempre che sei stato, il motivo per inviare nome utente / password con ogni richiesta è solo per l'autenticazione e lo stesso per l'invio di un token (generato dall'accesso processo) solo per decidere se il cliente ha l'autorizzazione a richiedere dati o meno, si violano le convinzioni REST solo quando si utilizzano nome utente / password o token di sessione per decidere quali dati mostrare! invece devi usarli solo per autenticazione (per mostrare i dati o non per mostrarli)

nel tuo caso dico SÌ questo è RESTy, ma prova ad evitare di usare sessioni php native nella tua API REST e inizia a generare i tuoi token hash che scadono in determinati periodi di tempo!


1
grazie. perché si dovrebbe evitare la sessione php nativa e usare invece i propri token hash?
Matteo,

non c'è nessun motivo brillante che dico, solo per maggiore sicurezza e maggiore controllo.
EvilThinker,

Questo è meglio della risposta accettata. Almeno, accetta il suggerimento come RESTy, il che ha senso. Tuttavia, non vedo perché le informazioni trasmesse non possano essere utilizzate per eseguire autorizzazioni dipendenti dall'utente. Alcuni utenti potrebbero avere accesso ad alcuni dati e altri no. Ciò non rende il protocollo non RESTful.

8

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


11
@ unforgiven3 Fintanto che il token restituito viene utilizzato solo per autenticare l'utente e non utilizzato dal server per associare l'utente a un altro stato memorizzato sul server, non vedo la violazione di vincoli REST.
Darrel Miller,

4
@ unforgiven3 Il token restituito dal server è, in effetti, la prova che l'utente è chi dice di essere. Pertanto, invece di ogni richiesta, inclusi nome utente e password, ogni richiesta include il token, costruito in modo tale che il server possa essere sicuro della sua veridicità.
Darrel Miller,

1
@ unforgiven3, Darrel ha ragione. Il token echo back dovrebbe essere inviato dal client su ogni richiesta HTTP, proprio come nell'autenticazione digest di base, fino alla scadenza del token. Quando ciò accade, il client può ripetere l'accesso, facoltativamente chiedendo all'utente le credenziali o altro. Potrei elaborare la risposta, se vuoi. modifica: (E grazie per tenere il passo con le risposte alle vecchie domande!)
mogsie

1
Nessun problema, mogsie, sempre interessante discutere di questo tipo di cose :-) Penso di vedere dove state andando ragazzi, sfortunatamente non capisco abbastanza sull'autenticazione del digest per capirlo davvero (per lo più non lo so capire come il token viene inviato indietro ogni richiesta HTTP, ma sembra essere un dettaglio di implementazione). Tuttavia, ora vedo perché questo metodo non viola i principi REST. Grazie per le risposte!
Rob,

6
@ unforgiven3, Questo può essere d'aiuto: il token è un'informazione firmata. Quindi è autonomo. Il server può convalidare il token senza controllare uno stato precedentemente memorizzato. Quindi è solo uno stato che viene archiviato sul client e trasferito avanti e indietro.
Iravanchi,

5

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

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

Sarebbe male avere un servizio REST, diciamo, / session, che accetta una richiesta GET, in cui si passerebbe un nome utente / password come parte della richiesta e restituisce un token di sessione se l'autenticazione ha esito positivo, che potrebbe essere poi passato insieme alle successive richieste? Ha senso dal punto di vista del RESTO o manca il punto?

L'idea generale della sessione è quella di creare applicazioni stateful utilizzando 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. Un'applicazione veramente RESTful manterrà lo stato sul lato client, inviando tutte le variabili necessarie tramite HTTP, preferibilmente nell'URI.

Esempio: ricerca con impaginazione. Avresti URL nel modulo

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

Ha molto in comune con gli URL con segnalibri


4
Tuttavia, le informazioni di autenticazione non sono accessibili tramite URI: tutti parlano dell'invio di informazioni di autenticazione come parte dell'intestazione della richiesta. In che modo differisce dall'includere un token di sessione con la richiesta? Non sto dicendo di utilizzare il token di sessione nell'URI, ma nei dati passati nella richiesta.
Rob,

L'autenticazione stabilisce se si è autorizzati a eseguire tale azione e l'applicazione RESTful non influisce sul risultato.
Vartec,

4
Un token di sessione stabilisce anche se sei autorizzato a eseguire quell'azione. Cosa vuoi dire che non influenzerebbe il suo risultato? Se il chiamante non è autorizzato, viene visualizzato un errore Non autorizzato. Stessa cosa con un token di sessione. Davvero non vedo la differenza?
Rob,

3
No, il token di sessione è un handle per lo stato salvato sul server. Questo non è RESTful. Per quanto riguarda il Non autorizzato, non vedo questo come risultato. Preferirei considerarlo un'eccezione (come in try / catch).
vartec,

Abbastanza giusto, vartec - ha senso. Grazie per il follow-up!
Rob,

3

Penso che il tuo suggerimento sia OK, se vuoi controllare la durata della sessione del cliente. Penso che l'architettura RESTful ti incoraggi a sviluppare applicazioni senza stato. Come scriveva @ 2pence "ogni richiesta HTTP dovrebbe contenere abbastanza informazioni da sola affinché il suo destinatario le elabori per essere in completa armonia con la natura apolide di HTTP" .

Tuttavia, non sempre è così, a volte l'applicazione deve dire quando il client accede o si disconnette e per mantenere risorse come blocchi o licenze basate su queste informazioni. Vedi la mia domanda di follow-up per un esempio di questo caso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.