Puoi aiutarmi a capire questo? “Errori comuni di REST: le sessioni sono irrilevanti”

Disclaimer: Sono nuovo nella scuola di pensiero REST, e sto cercando di avvolgere la mia mente intorno ad esso.

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 è quello che dice la pagina:

Non dovrebbe esserci bisogno di 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. Quindi 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 all’object “itinerario creatore” di creare un nuovo itinerario. Puoi iniziare a riempire gli spazi vuoti, ma poi ottenere componenti completamente diversi altrove sul web per riempire altri spazi vuoti. Non c’è nessuna sessione quindi non c’è alcun problema di migrazione dello stato della sessione tra client. Non esiste inoltre alcun problema di “affinità di sessione” nel server (sebbene continuino a verificarsi problemi di bilanciamento del carico).

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 accetti una richiesta GET, in cui dovresti inserire un nome utente / password come parte della richiesta e restituire un token di sessione se l’autenticazione ha avuto successo, che potrebbe essere poi passato insieme alle richieste successive? Questo ha senso da un punto di vista REST, o è che manca il punto?

Per essere RESTful, ogni richiesta HTTP dovrebbe portare sufficienti informazioni da sola per il suo destinatario per elaborarla in completa armonia con la natura senza stato di HTTP.

Ok, ho capito 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 al digest . E sì, un intercettatore può catturare le credenziali dell’utente. Uno quindi crittograferebbe tutti i dati inviati e ricevuti utilizzando Transport Layer Security (TLS) .

Sarebbe male avere un servizio REST, ad esempio, / session, che accetti una richiesta GET, in cui dovresti inserire un nome utente / password come parte della richiesta e restituire un token di sessione se l’autenticazione ha avuto successo, che potrebbe essere poi passato insieme alle richieste successive? Questo ha senso da un punto di vista REST, o è che manca il punto?

Questo non sarebbe RESTful dal momento che porta lo stato, ma è comunque abbastanza comune poiché è una comodità per gli utenti; un utente non deve accedere ogni volta.

Quello che descrivi in ​​un “token di sessione” viene comunemente definito 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.

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).

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

nel tuo caso dico SÌ questo è RESTy, ma cerca di evitare l’utilizzo di sessioni PHP native nella tua API REST e inizia a generare i tuoi token hash che scadono in determinati intervalli di tempo!

No, non manca il punto. Il 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.

Ok, ho capito che l’autenticazione HTTP viene eseguita automaticamente su ogni messaggio, ma come?

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

Sarebbe male avere un servizio REST, ad esempio, / session, che accetti una richiesta GET, in cui dovresti inserire un nome utente / password come parte della richiesta e restituire un token di sessione se l’autenticazione ha avuto successo, che potrebbe essere poi passato insieme alle richieste successive? Questo ha senso da un punto di vista REST, o è che manca il punto?

L’intera idea di sessione è quella di creare applicazioni stateful usando il protocollo stateless (HTTP) e il client stupido (browser web), mantenendo lo stato sul lato server. Uno dei principi REST è “Ogni risorsa è indirizzabile in modo univoco utilizzando una syntax universale da utilizzare nei collegamenti ipermediali” . Le variabili di sessione sono qualcosa a cui non è ansible 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 

Ha molto in comune con gli URL bookmarkable

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 per consentire al suo destinatario di elaborarla in completa armonia con la natura stateless di HTTP” .

Tuttavia, non sempre è così, a volte l’applicazione deve sapere quando il client esegue l’accesso o si disconnette e per mantenere le risorse come blocchi o licenze in base a queste informazioni. Vedi la mia domanda di follow-up per un esempio di questo caso.