Se le applicazioni REST dovrebbero essere apolidi, come gestite le sessioni?


536

Ho bisogno di qualche chiarimento. Ho letto di REST e ho creato applicazioni RESTful. Secondo Wikipedia, il REST stesso è definito come trasferimento di stato rappresentativo . Pertanto non capisco tutto questo apolide gobbledeygook che tutti continuano a vomitare.

Da Wikipedia:

In qualsiasi momento particolare, un client può essere in transizione tra gli stati dell'applicazione o "a riposo". Un client in uno stato di riposo è in grado di interagire con il suo utente, ma non crea alcun carico e non consuma spazio di archiviazione per client sul set di server o sulla rete.

Stanno solo dicendo di non usare l'archivio dati a livello di sessione / applicazione ???

Ottengo che un obiettivo di REST sia rendere coerente e disponibile l'accesso all'URI, ad esempio, invece di nascondere le richieste di paging all'interno dei post, rendendo il numero di pagina di una richiesta parte dell'URI GET. È sensato per me. Ma sembra che stia esagerando dicendo che nessun dato per client (dati di sessione) dovrebbe mai essere archiviato sul lato server.

E se avessi una coda di messaggi e il mio utente volesse leggere i messaggi, ma mentre li leggeva, voleva bloccare alcuni messaggi dei mittenti che arrivavano per la durata della sua sessione? Non avrebbe senso archiviarlo in un posto sul lato server e far sì che il server invii solo messaggi (o ID messaggio) che non sono stati bloccati dall'utente?

Devo davvero inviare l'intero elenco di mittenti di messaggi da bloccare ogni volta che richiedo il nuovo elenco di messaggi? L'elenco dei messaggi per me pertinenti non dovrebbe / non dovrebbe nemmeno essere una risorsa pubblicamente disponibile in primo luogo.

Ancora una volta, sto solo cercando di capirlo. Qualcuno per favore chiarire.


Aggiornare:

Ho trovato una domanda di overflow dello stack che ha una risposta che non mi ha portato fino in fondo: come gestire lo stato in REST che dice che lo stato del client che è importante dovrebbe essere trasferito su ogni richiesta .... .. sembra un sacco di spese generali ... È vero ??


2
@ S.Lott: non penso che sia intenzionalmente fuorviante. Penso che sia un malinteso a causa della terminologia confusa.
SOLO IL MIO OPINIONE corretta,

2
@SOLO IL MIO OPINIONE corretto: ipotesi interessante. Non potevo credere a una cosa del genere, dato che è ovvio che "apolide" significa che lo stesso protocollo REST è apolide; che non dice nulla sullo stato dell'applicazione sottostante e sull'aggiornamento con richieste PUT, POST e DELETE.
S.Lott

@ S.Lott: lo stesso protocollo HTTP è stateless. Da quello che abbiamo discusso di seguito, REST è un punto di vista su come costruire la tua app senza avere il server web che gestisce lo stato della sessione (al contrario di altri tipi di stato in cose come il DB). Non pensavo nemmeno che REST fosse un protocollo, ma piuttosto una visione su come usare il protocollo HTTP. Pensavo che voi ragazzi avete chiarito che si trattava di come scalare la vostra applicazione facendo in modo che il lato client memorizzasse tutti i dati di sessione specifici del client e rendesse gli accessi agli URI il più idempotenti possibili, tranne dove non dovevano essere. Forse no ... :(
Zak

1
"Forse no .." Cosa significa? Hai una nuova domanda? Sentiti libero di cercarlo. Se non esiste qui, chiedilo.
S.Lott,

Qualcuno ha letto Reber in Practice di Webber, Parastatidis e Robinson (o altrimenti visto il loro esempio di restbucks)? Le risposte che seguono hanno senso, ma sicuramente gli ordini di caffè nell'esempio restbucks sono indicativi di un cliente? Il numero di ordini aumenta in base al numero di clienti. Dov'è la linea tra lo stato del client e una risorsa?
Rikki,

Risposte:


340

Statelessness significa che ogni richiesta HTTP avviene in completo isolamento. Quando il client effettua una richiesta HTTP, include tutte le informazioni necessarie affinché il server soddisfi tale richiesta. Il server non si basa mai su informazioni provenienti da richieste precedenti. Se tali informazioni fossero importanti, il cliente dovrebbe inviarle nuovamente nella richiesta successiva. L'apolidia porta anche nuove funzionalità. È più semplice distribuire un'applicazione senza stato su server con bilanciamento del carico. Anche un'applicazione senza stato è facile da memorizzare nella cache.

Esistono in realtà due tipi di stato. Stato dell'applicazione che risiede sul client e Stato della risorsa che risiede sul server.

Un servizio Web deve preoccuparsi solo dello stato della tua applicazione quando stai effettivamente facendo una richiesta. Il resto del tempo, non sa nemmeno che esisti. Ciò significa che ogni volta che un client effettua una richiesta, deve includere tutti gli stati dell'applicazione che il server dovrà elaborare.

Lo stato delle risorse è lo stesso per ogni client e la sua posizione corretta è sul server. Quando carichi un'immagine su un server, crei una nuova risorsa: la nuova immagine ha il suo URI e può essere la destinazione di richieste future. Puoi recuperare, modificare ed eliminare questa risorsa tramite HTTP.

Spero che questo aiuti a differenziare il significato di apolidia e vari stati.


4
Ciò significa che ogni volta che viene inviata una richiesta il client deve inviare il proprio utente / password per l'autenticazione? Perché suppongo che l'archiviazione di una sessione, anche se si trova su un db no-sql condiviso tra tutti i server, non sia senza stato o è?
Carlos Navarro Astiasarán,

1
@ CarlosNavarroAstiasarán ci sono varie tecniche per gestire l'autenticazione senza stato. Google JWT per esempio.
geoidesic,

1
@geoidesic: "Poiché i token Web JSON sono senza stato, non è possibile invalidarli senza memorizzare lo stato del server, vanificando così il vantaggio dei token senza stato." Wikipedia
ulatekh,

@ulatekh Questa è una grave travisamento di ciò che puoi fare con i token. È abbastanza semplice archiviare un ID approvato insieme al token e accettare solo token che hanno un ID approvato come reclamo. Stateless non significa che non è possibile qualcosa in un database. In sostanza, si memorizza un ID nel database che deve corrispondere allo stesso ID nel token. Per revocare il token è necessario rimuovere l'ID dal database. Nessuno stato viene ricordato nel servizio stesso. O ancora meglio archiviare la chiave del segno con l'utente nel database e revocare la chiave.
Andrew T Finnell,

@AndrewTFinnell: se è necessario archiviare l'ID approvato sul server, è necessario che sia archiviato su tutti i potenziali server in grado di elaborare il login REST, il che potrebbe comportare molto stato del server in un'architettura di server Web massicciamente parallela.
ulatekh,

491

La spiegazione fondamentale è:

Nessuno stato della sessione client sul server.

Per apolide significa che il server non memorizza alcuno stato sulla sessione client sul lato server.

La sessione client è memorizzata sul client. Il server è stateless significa che ogni server può servire qualsiasi client in qualsiasi momento, non ci sono affinità di sessione o sessioni appiccicose . Le informazioni relative alla sessione vengono archiviate sul client e passate al server secondo necessità.

Ciò non preclude ad altri servizi con cui il web server parla di mantenere lo stato su oggetti business come i carrelli della spesa, ma non lo stato corrente dell'applicazione / sessione del client.

Lo stato dell'applicazione del client non deve mai essere archiviato sul server, ma passato dal client in ogni luogo che ne ha bisogno.

Ecco da dove proviene la ST in REST , State Transfer . Si trasferisce lo stato in giro invece che il server lo memorizzi. Questo è l'unico modo per ridimensionare a milioni di utenti simultanei. Se non altro perché milioni di sessioni sono milioni di sessioni.

Il carico della gestione della sessione è ammortizzato su tutti i client, i client memorizzano lo stato della sessione e i server possono servire molti ordini di grandezza o più client in modo apolide.

Anche per un servizio che ritieni sia necessario solo negli anni 10 di migliaia di utenti simultanei, dovresti comunque rendere il tuo servizio senza stato. Decine di migliaia sono ancora decine di migliaia e ci saranno costi di tempo e spazio associati.

Stateless è il modo in cui il protocollo HTTP e il web in generale sono stati progettati per funzionare ed è un'implementazione complessivamente più semplice e si dispone di un singolo percorso di codice anziché di una serie di logiche lato server per mantenere un gruppo di stato della sessione.

Esistono alcuni principi di implementazione molto basilari:

Questi sono principi e non implementazioni, il modo in cui si soddisfano questi principi può variare.

In sintesi, i cinque principi chiave sono:

  1. Dai a ogni "cosa" un ID
  2. Collega le cose insieme
  3. Usa metodi standard
  4. Risorse con rappresentazioni multiple
  5. Comunicare senza stato

Non c'è nulla sull'autenticazione o l'autorizzazione nella tesi di REST .

Perché non c'è nulla di diverso dall'autenticare una richiesta RESTful da una richiesta che non lo è. L'autenticazione è irrilevante per la discussione RESTful.

Spiegare come creare un'applicazione senza stato per esigenze particolari è troppo ampio per StackOverflow.

L'implementazione dell'autenticazione e dell'autorizzazione per quanto riguarda il REST è ancora più ampia e vari approcci alle implementazioni sono spiegati in modo molto dettagliato su Internet in generale.

I commenti che richiedono aiuto / informazioni al riguardo / dovranno essere contrassegnati come Non più necessari .


22
Sembra un'affermazione piuttosto audace che è l' unico modo per ridimensionare milioni di utenti. Perché le sessioni lato server non possono essere solo un altro servizio?
Zak,

27
@Zak: Perché milioni di sessioni sono milioni di sessioni. Il punto è evitare il sovraccarico di tutta questa gestione della sessione.
S.Lott,

91
non è audacia, è esperienza

21
Nulla nella mia risposta implica una soluzione basata sull'accesso al database su ogni richiesta, se pensi che lo faccia, è un fallimento da parte tua comprendere l'autenticazione e l'autorizzazione su quella scala. L'autenticazione può essere implicita nello stato, pensi che Facebook faccia un "accesso al database" su ogni richiesta della sua API REST? O Google del resto? suggerimento: no

6
Quindi, se memorizzo lo stato utente in una cache distribuita, dico memcache, e tutto il mio server web ora non ha bisogno di memorizzare alcuno stato ma va e ottiene stato da memcache, posso considerare questa applicazione senza stato?
Jaskey,

76

Stanno solo dicendo di non usare l'archivio dati a livello di sessione / applicazione ???

No. Non lo stanno dicendo in modo banale.

Stanno dicendo di non definire una "sessione". Non effettuare il login. Non disconnettersi. Fornire le credenziali con la richiesta. Ogni richiesta è sola.

Hai ancora archivi di dati. Hai ancora autenticazione e autorizzazione. Non perdi tempo a stabilire sessioni e a mantenere lo stato della sessione.

Il punto è che ogni richiesta (a) è completamente sola e (b) può essere banalmente trasferita in una gigantesca server farm parallela senza alcun lavoro effettivo. Apache o Squid possono passare richieste RESTful alla cieca e con successo.

E se avessi una coda di messaggi e il mio utente volesse leggere i messaggi, ma mentre li leggeva, voleva bloccare alcuni messaggi dei mittenti che arrivavano per la durata della sua sessione?

Se l'utente desidera un filtro, fornisci semplicemente il filtro per ogni richiesta.

Non avrebbe senso ... il server deve inviare solo messaggi (o ID messaggio) che non sono stati bloccati dall'utente?

Sì. Fornire il filtro nella richiesta URI RESTful.

Devo davvero inviare l'intero elenco di mittenti di messaggi da bloccare ogni volta che richiedo il nuovo elenco di messaggi?

Sì. Quanto può essere grande questo "elenco di mittenti di messaggi da bloccare"? Un breve elenco di PK?

Una richiesta GET può essere molto grande. Se necessario, puoi provare una richiesta POST anche se sembra una specie di query.


28
"Non effettuare il login. Non disconnettersi. Fornire le credenziali con la richiesta." Vedo sempre risposte come queste nelle domande su come rimanere apolidi in un'API REST senza dettagli su dove / come si dovrebbero archiviare tali credenziali sul client. Sicuramente non dovremmo archiviare nome utente e password nella memoria locale!
BeniRose,

2
@BeniRose non possiamo archiviare un token nell'archivio locale e utilizzare quel token nelle richieste che identificheranno in modo univoco l'utente?
Nikhil Sahu,

1
Localstorage ha molti problemi di sicurezza da quello che ho capito. Ma ci sono anche
molte

3
si utilizza JWT che ha una firma, la verifica della firma è veloce in modo da poter verificare la validità di quello stato.
Archimede Trajano,

36

Hai assolutamente ragione, supportare interazioni completamente senza stato con il server comporta un ulteriore onere per il client. Tuttavia, se si considera il ridimensionamento di un'applicazione, la potenza di calcolo dei client è direttamente proporzionale al numero di client. Pertanto il ridimensionamento a un numero elevato di clienti è molto più fattibile.

Non appena si assegna un po 'di responsabilità al server per la gestione di alcune informazioni relative alle interazioni di un cliente specifico, tale onere può aumentare rapidamente per consumare il server.

È un compromesso.


32

Vista storica della gestione dello stato dell'applicazione utente

Le sessioni in senso tradizionale mantengono lo stato dell'utente nell'applicazione all'interno del server. Potrebbe trattarsi della pagina corrente in un flusso o di ciò che è stato precedentemente immesso ma non è stato ancora memorizzato nel database principale.

La ragione di questa esigenza era la mancanza di standard sul lato client per mantenere efficacemente lo stato senza creare applicazioni o plug-in specifici per client (cioè specifici per browser).

La richiesta di intestazione HTML5 e XML ha nel tempo standardizzato l'idea di archiviare dati complessi, incluso lo stato dell'applicazione in modo standard sul lato client (ad es. Browser) senza ricorrere ad andare avanti e indietro tra il server.

Utilizzo generale dei servizi REST

I servizi REST sono generalmente chiamati quando c'è una transazione che deve essere eseguita o se deve recuperare i dati.

I servizi REST devono essere chiamati dall'applicazione lato client e non direttamente dall'utente finale.

autenticazione

Per qualsiasi richiesta al server, parte della richiesta deve contenere il token di autorizzazione. Il modo in cui è implementato è specifico dell'applicazione, ma in generale è un BASICoCERTIFICATE forma di autenticazione.

L'autenticazione basata su modulo non viene utilizzata dai servizi REST. Tuttavia, come notato sopra, i servizi REST non sono pensati per essere chiamati dall'utente, ma dall'applicazione. L'applicazione deve riuscire a ottenere il token di autenticazione. Nel mio caso ho usato i cookie con JASPIC con OAuth 2.0 per connettermi a Google per l'autenticazione e l' autenticazione HTTP semplice per i test automatizzati. Ho anche usato l' autenticazione HTTP Header tramite JASPIC anche per i test locali (anche se lo stesso approccio può essere eseguito in SiteMinder)

Come per quegli esempi, l'autenticazione è gestita sul lato client (sebbene SiteMinder o Google memorizzino la sessione di autenticazione alla loro estremità), non c'è nulla che possa essere fatto su quello stato, ma non fa parte dell'applicazione del servizio REST.

Richieste di recupero

Le richieste di recupero in REST sono GEToperazioni in cui è richiesta una risorsa specifica ed è memorizzabile nella cache. Non sono necessarie sessioni server perché la richiesta ha tutto il necessario per recuperare i dati: autenticazione e URI.

Script di transazione

Come notato sopra, l'applicazione sul lato client stesso chiama i servizi REST insieme all'autenticazione che gestisce anche sul lato client.

Ciò che ciò significa per i servizi REST [se eseguito correttamente] è che una singola richiesta al server REST conterrà tutto ciò che è necessario per un'operazione di un singolo utente che fa tutto ciò che è necessario in una singola transazione, uno Script di transazione è ciò che il modello è chiamato.

Questo viene fatto attraverso una POSTrichiesta di solito, ma PUTpossono essere utilizzati anche altri come .

Molti esempi inventati di REST (io stesso ho fatto questo) hanno provato a seguire gran parte di ciò che è stato definito nel protocollo HTTP, dopo aver deciso che ero più pragmatico e l'ho lasciato solo a GET e POST . Il POSTmetodo non deve nemmeno implementare il modello POST-REDIRECT-GET.

Indipendentemente da ciò, come ho notato sopra, l'applicazione lato client sarà quella che chiama il servizio e chiamerà la POSTrichiesta con tutti i dati solo quando è necessario (non ogni volta). Ciò impedisce richieste costanti al server.

votazione

Sebbene REST possa essere utilizzato anche per il polling, non lo consiglio a meno che non sia necessario utilizzarlo a causa della compatibilità del browser. Per questo vorrei usare WebSocket per il quale avevo progettato anche un contratto API . Un'altra alternativa per i browser più vecchi è CometD.


27

REST è molto astratto. Aiuta ad avere alcuni esempi buoni, semplici e reali.

Prendi ad esempio tutte le principali app di social media: Tumblr, Instagram, Facebook e Twitter. Tutti hanno una vista a scorrimento continuo dove più scorri verso il basso, più contenuti vedi, sempre più indietro nel tempo. Tuttavia, abbiamo vissuto tutti quel momento in cui perdi la posizione in cui sei stato spostato e l'app ti reimposta in alto. Come se uscissi dall'app, quindi quando la riapri, sarai di nuovo in cima.

Il motivo è che il server non ha memorizzato lo stato della sessione. Purtroppo, la posizione di scorrimento è stata appena memorizzata nella RAM sul client.

Fortunatamente non è necessario riconnettersi quando ci si riconnette, ma ciò è dovuto al fatto che anche il certificato di accesso archiviato sul lato client non è scaduto. Elimina e reinstalla l'app e dovrai accedere di nuovo, perché il server non ha associato il tuo indirizzo IP alla sessione.

Non hai una sessione di accesso sul server, perché rispettano REST.


Ora gli esempi precedenti non riguardano affatto un browser Web, ma sul back-end le app comunicano tramite HTTPS con i loro server host. Il punto è che REST non deve coinvolgere cookie, browser, ecc. Esistono vari modi per memorizzare lo stato della sessione sul lato client.

Ma parliamo dei browser web per un secondo, perché questo porta ad un altro grande vantaggio di REST di cui nessuno parla qui.

Se il server ha tentato di memorizzare lo stato della sessione, come dovrebbe identificare ogni singolo client?

Non è stato possibile utilizzare il proprio indirizzo IP, poiché molte persone potrebbero utilizzare lo stesso indirizzo su un router condiviso. Allora come?

Non può utilizzare l'indirizzo MAC per molti motivi, non ultimo perché è possibile accedere contemporaneamente a più account Facebook diversi su browser diversi oltre all'app. Un browser può facilmente fingere di essere un altro e gli indirizzi MAC sono altrettanto facili da falsificare.

Se il server deve archiviare uno stato lato client per identificarti, deve memorizzarlo nella RAM più a lungo del tempo necessario per elaborare le tue richieste, oppure deve memorizzare nella cache quei dati. I server hanno quantità limitate di RAM e cache, per non parlare della velocità del processore. Lo stato lato server si aggiunge a tutti e tre, in modo esponenziale. Inoltre, se il server memorizzerà uno stato delle sessioni, dovrà memorizzarlo separatamente per ciascun browser e app con cui si è attualmente connessi e anche per ciascun dispositivo diverso che si utilizza.


Quindi ... spero che ora capisca perché REST è così importante per la scalabilità. Spero che tu possa iniziare a capire perché lo stato della sessione sul lato server è la scalabilità del server quali sono le incudini saldate sull'accelerazione dell'auto.


Il punto in cui le persone si confondono è pensando che "stato" si riferisca, come, alle informazioni archiviate in un database. No, si riferisce a qualsiasi informazione che deve essere nella RAM del server quando la si utilizza.


13

Vedo che il problema di base qui è confondere la Sessione con lo Stato . E mentre REST specifica che NON è necessario memorizzare lo stato sul server, nulla impedisce di memorizzare una sessione utente .

Gestire lo stato sul server significa che il tuo server sa esattamente cosa sta facendo il client (quale pagina sta visualizzando in quale sezione dell'applicazione). E questo è ciò che non dovresti fare.

Sono d'accordo con le altre persone che affermano che è necessario mantenere l'archiviazione della sessione a una dimensione minima; e mentre questo è buon senso, in realtà dipende anche dall'applicazione. Quindi, in breve, è comunque possibile mantenere una sessione con i dati memorizzati nella cache per gestire le richieste con meno carico sul server e gestire l'autenticazione fornendo un token di autenticazione / accesso temporaneo che il client deve utilizzare. Ogni volta che la sessione / token è scaduta, generane una nuova e chiedi al client di usarla.

Qualcuno potrebbe obiettare che il client dovrebbe generare meglio il token. Dico che funziona in entrambi i modi e dipenderà dall'applicazione e da chi lavorerà con l'API.

Anche mantenere alcuni dati di sessione sensibili sul server dovrebbe essere il modo giusto di fare. Non puoi fidarti del cliente per mantenere il proprio carrello che (ad esempio) contiene un campo chiamato "isFreeGift". Tali informazioni dovrebbero essere conservate sul server.

Il collegamento video fornito da Santanu Dey nella sua risposta è utile. Guardalo se non l'hai fatto.

Solo una nota a margine: sembra che tutte le risposte già fornite sembrano non tenere conto del fatto che alcune operazioni potrebbero causare un carico pesante sul server. Ciò è rilevante in termini di consumo di energia, consumo di hardware e costi (per server noleggiati dal ciclo della CPU). Un buon sviluppatore non dovrebbe essere pigro nell'ottimizzare la propria applicazione, anche se l'operazione può essere eseguita molto rapidamente su una CPU moderna su un server noleggiato per il quale non paga la bolletta dell'elettricità e della manutenzione.

Anche se la domanda ha qualche anno, spero che la mia risposta sia ancora utile.


4
Sono generalmente d'accordo con questo sentimento, ma c'è stata una tendenza recente a sostenere che anche un identificatore di sessione non dovrebbe essere archiviato sul server. Devo ancora scoprire qual è la soluzione alternativa, JWT è ben pubblicizzato, ma viene fornito con una manciata di gotchas
BeniRose

11

Stateless significa che lo stato del servizio non persiste tra richieste e risposte successive. Ogni richiesta ha le proprie credenziali utente ed è autenticata individualmente. Ma in stateful ogni richiesta è nota da qualsiasi richiesta precedente. Tutte le richieste stateful sono orientate alla sessione, ovvero ogni richiesta deve conoscere e conservare le modifiche apportate alle richieste precedenti.

L'applicazione bancaria è un esempio di applicazione stateful. Dove l'utente accede per primo, quindi effettua la transazione e si disconnette. Se dopo la disconnessione l'utente tenterà di effettuare la transazione, non sarà in grado di farlo.

Sì, il protocollo http è essenzialmente un protocollo senza stato ma per renderlo di stato ci facciamo dei cookie HTTP. Quindi, è SOAP per impostazione predefinita. Ma può essere anche allo stato, dipende dal framework che stai usando.

HTTP è senza stato ma possiamo comunque mantenere la sessione nella nostra applicazione java utilizzando un meccanismo di tracciamento della sessione diverso.

Sì, possiamo anche mantenere la sessione nel servizio web sia che si tratti di REST o SOAP. Può essere implementato utilizzando qualsiasi libreria di terze parti oppure è possibile implementarlo da soli.

Tratto da http://gopaldas.org/webservices/soap/webservice-is-stateful-or-stateless-rest-soap


11

Non c'è il cucchiaio.

Non pensare all'apolidia come "inviare tutte le tue cose al server ancora e ancora". Non c'è modo. Ci sarà sempre lo stato - dopo tutto il database stesso è un tipo di stato, sei un utente registrato, quindi qualsiasi set di informazioni sul lato client non sarà valido senza il lato server. Tecnicamente, non sei mai veramente apolide.

Una parola sull'accesso ogni volta dibattito di

Cosa significa anche non tenere una sessione e accedere ogni volta? Alcuni significano "invia la password ogni volta", è semplicemente stupido. Alcuni dicono "no, certo che no, invia invece un token " - ecco, la sessione PHP sta facendo quasi esattamente questo. Invia un ID di sessione che è una specie di token e ti aiuta a raggiungere le tue cose personali senza rinviare ogni volta u / pw. È anche abbastanza affidabile e ben testato. E sì, conveniente, che può trasformarsi in uno svantaggio, vedi il prossimo paragrafo.

Ridurre l'impronta

Ciò che dovresti fare , invece, e ciò che ha davvero senso, è ridurre al minimo la tua impronta del server web. Lingue come PHP rendono molto semplice inserire tutto nella memoria della sessione, ma le sessioni hanno un prezzo. Se hai diversi server web, devono condividere le informazioni sulla sessione, perché condividono anche il carico - ognuno di loro potrebbe dover soddisfare la richiesta successiva.

Un archivio condiviso è un must. Il server deve sapere almeno se qualcuno ha effettuato l'accesso o meno. (E se infastidisci il database ogni volta che devi decidere, sei praticamente condannato.) Gli archivi condivisi devono essere molto più veloci del database. Questo porta la tentazione: okay, ho una memoria molto veloce, perché non fare tutto lì? - ed è lì che le cose vanno male per l'altro.

Quindi stai dicendo: mantenere la memoria di sessione al minimo?

Ancora una volta, è una tua decisione. Puoi archiviare materiale lì per motivi di prestazioni (il database è quasi sempre più lento di Redis), puoi archiviare informazioni in modo ridondante, implementare la tua memorizzazione nella cache, qualunque cosa - tieni presente che i server Web avranno un carico maggiore se immagazzini un sacco di immondizia su di essi. Inoltre, se si rompono sotto carichi pesanti (e lo faranno), perderai informazioni preziose; con il modo di pensare REST, tutto ciò che accade in questo caso è che il client invia di nuovo la stessa (!) richiesta e questa volta viene servita.

Come farlo subito?

Nessuna soluzione adatta a tutti qui. Direi di scegliere un livello di apolidia e andare con quello. Le sessioni possono essere amate da alcuni e odiate da altri ma non vanno da nessuna parte. Con ogni richiesta, invia quante più informazioni ha senso, forse un po 'di più; ma non interpretare l'apolidia come non avere una sessione, né come accedere ogni volta. In qualche modo il server deve sapere che sei tu ; Gli ID di sessione PHP sono un buon metodo, i token generati manualmente sono un altro.

Pensa e decidi, non lasciare che le tendenze del design pensino per te.


1
"Pensa e decidi, non lasciare che le tendenze del design pensino per te." purtroppo oggi è molto comune seguire stupidamente le tendenze. A volte leggendo SO otterrai le stesse risposte solo a causa della tendenza.
00k,

Sì, l'ho visto su molti argomenti e quando mi rendo conto di ciò che sta accadendo, a volte smetto di litigare. All'epoca tutti erano pazzi di come la content box fosse migliore della border box; era un modo per mostrare odio contro IE. Poi è arrivato il bootstrap e improvvisamente tutti sono stati un credente border-box. Le tendenze arrivano ma poi vanno. Usa goto, usa le tabelle, usa iframe, basta sapere cosa stai facendo e perché. I Trendist cercheranno di abbatterti, quindi si registreranno e pagheranno sul tuo sito. Il mondo è di nuovo salvato.
dkellner,

@dkellner Non ho capito quella parte: "Il server deve sapere almeno se qualcuno ha effettuato l'accesso o meno. (E se disturbi il database ogni volta che devi decidere, sei praticamente condannato.)". Supponi di archiviare i dati della sessione nel database con PHP. Perché la query del DB per l'accesso non è valida (la condanna è una parola forte) poiché comunque ci saranno molte richieste di DB successive per ottenere i dati utente completi e altre cose, in base all'ID della sessione PHP? In altre parole, le query DB sono inevitabili in ogni caso. Inoltre, se non ricevi un ID sessione PHP, sai che l'utente non è autenticato, non è necessario eseguire una query.
user2923322

Quando hai migliaia o addirittura milioni di utenti, non puoi permetterti il ​​lusso di connetterti a db ogni volta che vuoi fare un keepalive, un aggiornamento della posizione, un sondaggio sui messaggi o qualsiasi cosa abbia bisogno di un breve check-in. Devi implementare queste chiamate senza (o con un minimo) accesso al database, ecco perché sto dicendo che può essere letale se costruisci il tuo intero concetto attorno a db. Ancora una volta, ci possono essere casi in cui una soluzione db ben progettata funzionerà, ma il programmatore tipico risolverà qualsiasi cosa dicendo "okay, prima ci colleghiamo e prendiamo alcune informazioni utente". Pratica Baaaad.
dkellner,


3

La principale differenza tra stateless e stateful è che i dati vengono restituiti ogni volta al server. In caso di apolidi, il cliente deve fornire tutte le informazioni, quindi potrebbe essere necessario passare molti parametri in ogni richiesta. In Stateful, il cliet passa quei parametri una volta e vengono mantenuti dal server fino a quando non vengono modificati nuovamente dal client.

IMO, API dovrebbe essere apolide che consente di scalare molto rapidamente.


2

Devi gestire la sessione client sul lato client. Ciò significa che devi inviare i dati di autenticazione con ogni richiesta e probabilmente, ma non necessario, hai una cache in memoria sul server, che abbina i dati di autenticazione alle informazioni dell'utente come identità, autorizzazioni, ecc ...

Questo vincolo di apolidia REST è molto importante. Senza applicare questo vincolo, l'applicazione lato server non si ridimensionerà bene, perché mantenere ogni singola sessione client sarà il suo tallone d'Achille .


Se invii dati di autenticazione con ogni richiesta, dove / come archiviare le credenziali sul client in modo che l'utente non debba reinserirle su ogni richiesta?
Ambra

1

Quando si sviluppa un servizio RESTful, per poter accedere è necessario che l'utente sia autenticato. Un'opzione possibile sarebbe quella di inviare nome utente e password ogni volta che si intende eseguire un'azione da parte dell'utente. In questo caso il server non memorizzerà affatto i dati di sessione.

Un'altra opzione è quella di generare un ID sessione sul server e inviarlo al client, in modo che il client sarà in grado di inviare ID sessione al server e autenticarsi con quello. Questo è molto più sicuro dell'invio di nome utente e password ogni volta, poiché se qualcuno mette la mano su quei dati, può impersonare l'utente fino a quando il nome utente e la password non vengono modificati. Puoi dire che anche l'ID di sessione può essere rubato e l'utente sarà impersonato in quel caso e hai ragione. Tuttavia, in questo caso la rappresentazione dell'utente sarà possibile solo mentre l'id di sessione è valido.

Se l'API RESTful prevede nome utente e password per modificare nome utente e password, anche se qualcuno ha impersonato l'utente utilizzando l'id di sessione, l'hacker non sarà in grado di bloccare l'utente reale.

Un ID sessione potrebbe essere generato dal blocco unidirezionale (crittografia) di qualcosa che identifica l'utente e aggiungendo il tempo all'ID sessione, in questo modo si potrebbe definire il tempo di scadenza della sessione.

Il server può o meno memorizzare gli ID di sessione. Naturalmente, se il server memorizza l'id di sessione, violerebbe i criteri definiti nella domanda. Tuttavia, è importante solo assicurarsi che l'id di sessione possa essere convalidato per l'utente specificato, il che non richiede la memorizzazione dell'ID di sessione. Immagina un modo per avere una crittografia unidirezionale di e-mail, ID utente e alcuni dati privati ​​specifici dell'utente, come il colore preferito, questo sarebbe il primo livello e in qualche modo aggiungere la data del nome utente alla stringa crittografata e applicare un due- modo crittografia. Di conseguenza, quando viene ricevuto un ID di sessione, il secondo livello potrebbe essere decrittografato per poter determinare quale nome utente l'utente afferma di essere e se l'ora della sessione è corretta. Se questo è valido, quindi il primo livello di crittografia potrebbe essere convalidato eseguendo nuovamente quella crittografia e verificando se corrisponde alla stringa. Non è necessario archiviare i dati della sessione per ottenere ciò.


questo ha senso
partito il

0

L'intero concetto è diverso ... Non è necessario gestire le sessioni se si sta tentando di implementare il protocollo RESTFul. In tal caso è meglio eseguire la procedura di autenticazione su ogni richiesta (mentre vi è un costo aggiuntivo in termini di prestazioni - la password di hashing sarebbe un buon esempio. Non un grosso problema ...). Se si utilizzano sessioni: come è possibile distribuire il carico su più server? Scommetto che il protocollo RESTFul ha lo scopo di eliminare qualsiasi sessione - non ne hai davvero bisogno ... Ecco perché si chiama "apolide". Le sessioni sono necessarie solo quando non è possibile memorizzare altro che Cookie sul lato client dopo che è stata effettuata una richiesta (ad esempio, utilizzare un browser non supportato da JavaScript / HTML5). In caso di client RESTFul "full optional" è generalmente sicuro archiviarlobase64(login:password) sul lato client (in memoria) fino a quando l'application non viene ancora caricata: l'applicazione viene utilizzata per accedere all'unico host e il cookie non può essere compromesso dagli script di terze parti ...

Consiglio vivamente di disabilitare l'autenticazione dei cookie per i servizi RESTFul ... controlla l'autent di base / digest - che dovrebbe essere sufficiente per i servizi basati su RESTFul.


3
Che cos'è a client side (in memory) e come è sicuro salvare base64(login:password)sul lato client?
RN Kushwaha,

1
Nulla è definito come "completamente sicuro". Tuttavia, puoi considerare di utilizzare OAuth2 fornendo una sicurezza migliore rispetto al salvataggio della stringa base64 per la richiesta API (Autent di base), se ti attieni all'autorizzazione di base, puoi utilizzare HTTPS per una migliore sicurezza.
felixwcf,

3
RN Kushwaha, questa è la domanda a cui nessuno sembra voler rispondere quando ti dicono di interrompere l'archiviazione della sessione sul server e l'archiviazione nel client.
BeniRose,

0

REST è apolide e non mantiene alcuno stato tra le richieste. I cookie / le intestazioni dei client sono impostati per mantenere lo stato dell'utente come l'autenticazione. Di 'che il nome utente / la password del cliente sono convalidati dal meccanismo di autenticazione di terze parti - gerneazione OTP di 2 ° livello ecc. Una volta che l'utente viene autenticato - le intestazioni / i cookie vengono a mancare all'endpoint del servizio esposto e possiamo assumere l'utente come autent poiché l'utente arriva con intestazioni / cookie validi . Ora alcune informazioni dell'utente come IP vengono mantenute nella cache e successivamente se la richiesta proviene dallo stesso IP (indirizzo mac) per le risorse elencate, l'utente è autorizzato. E la cache viene mantenuta per un determinato periodo di tempo che viene invalidato una volta scaduto il tempo. Quindi è possibile utilizzare la cache o le voci DB per conservare le informazioni in b / n delle richieste.


0

Stateless qui significa che lo stato o i metadati della richiesta non vengono gestiti sul lato server. Mantenendo ogni richiesta o stato dell'utente sul server, si porterebbero a colli di bottiglia delle prestazioni. Il server è appena richiesto con gli attributi richiesti per eseguire qualsiasi operazione specifica.

Per gestire le sessioni o offrire agli utenti un'esperienza personalizzata, è necessario mantenere alcuni metadati o lo stato delle preferenze dell'utente, la cronologia delle richieste passate. Questo può essere fatto mantenendo i cookie, gli attributi nascosti o nell'oggetto sessione.

Questo può mantenere o tenere traccia dello stato dell'utente nell'applicazione.

Spero che sia di aiuto!

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.