Cosa significa autenticazione RESTful e come funziona? Non riesco a trovare una buona panoramica su Google. La mia unica comprensione è che passi la chiave di sessione (remeberal) nell'URL, ma questo potrebbe essere terribilmente sbagliato.
Cosa significa autenticazione RESTful e come funziona? Non riesco a trovare una buona panoramica su Google. La mia unica comprensione è che passi la chiave di sessione (remeberal) nell'URL, ma questo potrebbe essere terribilmente sbagliato.
Risposte:
Come gestire l'autenticazione in un'architettura Client-Server RESTful è una questione di dibattito.
Comunemente, può essere raggiunto, nel mondo SOA su HTTP tramite:
Dovrai adattare, o ancor meglio mescolare quelle tecniche, per abbinare al meglio la tua architettura software.
Ogni schema di autenticazione ha i propri PRO e CON, a seconda dello scopo della politica di sicurezza e dell'architettura software.
Autenticazione HTTP di base su HTTPS
Questa prima soluzione, basata sul protocollo HTTPS standard, è utilizzata dalla maggior parte dei servizi web.
GET /spec.html HTTP/1.1
Host: www.example.org
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
È facile da implementare, disponibile per impostazione predefinita su tutti i browser, ma presenta alcuni inconvenienti noti, come la terribile finestra di autenticazione visualizzata sul browser, che persisterà (non esiste una funzione simile a LogOut qui), un consumo aggiuntivo di CPU sul lato server, e il fatto che il nome utente e la password siano trasmessi (tramite HTTPS) al Server (dovrebbe essere più sicuro lasciare che la password rimanga solo sul lato client, durante l'immissione da tastiera, e sia memorizzata come hash sicuro sul Server) .
Potremmo utilizzare l' autenticazione Digest , ma richiede anche HTTPS, poiché è vulnerabile agli attacchi MiM o Replay ed è specifico per HTTP.
Sessione tramite cookie
Ad essere onesti, una sessione gestita sul Server non è veramente Stateless.
Una possibilità potrebbe essere quella di conservare tutti i dati all'interno del contenuto dei cookie. E, in base alla progettazione, il cookie viene gestito sul lato server (il client, infatti, non tenta nemmeno di interpretare questi dati sui cookie: li restituisce al server solo ad ogni richiesta successiva). Ma questi dati sui cookie sono dati sullo stato dell'applicazione, quindi il client dovrebbe gestirli, non il server, in un puro mondo Stateless.
GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: theme=light; sessionToken=abc123
La stessa tecnica dei cookie è collegata a HTTP, quindi non è veramente RESTful, che dovrebbe essere indipendente dal protocollo, IMHO. È vulnerabile agli attacchi MiM o Replay .
Concesso tramite token (OAuth2)
Un'alternativa è inserire un token nelle intestazioni HTTP in modo che la richiesta sia autenticata. Questo è ciò che fa OAuth 2.0, ad esempio. Vedi RFC 6749 :
GET /resource/1 HTTP/1.1
Host: example.com
Authorization: Bearer mF_9.B5f-4.1JqM
In breve, questo è molto simile a un cookie e presenta gli stessi problemi: non apolidi, basandosi sui dettagli di trasmissione HTTP e soggetti a molte debolezze di sicurezza - tra cui MiM e Replay - quindi deve essere utilizzato solo su HTTPS. In genere, un JWT viene utilizzato come token.
Autenticazione query
L'autenticazione della query consiste nel firmare ogni richiesta RESTful tramite alcuni parametri aggiuntivi sull'URI. Vedi questo articolo di riferimento .
È stato definito come tale in questo articolo:
Tutte le query REST devono essere autenticate firmando i parametri della query ordinati in minuscolo, in ordine alfabetico utilizzando la credenziale privata come token di firma. La firma dovrebbe avvenire prima dell'URL che codifica la stringa di query.
Questa tecnica è forse la più compatibile con un'architettura Stateless e può anche essere implementata con una gestione delle sessioni leggere (utilizzando sessioni in memoria invece della persistenza del DB).
Ad esempio, ecco un esempio di URI generico dal link sopra:
GET /object?apiKey=Qwerty2010
dovrebbe essere trasmesso come tale:
GET /object?timestamp=1261496500&apiKey=Qwerty2010&signature=abcdef0123456789
La stringa che viene firmata è /object?apikey=Qwerty2010×tamp=1261496500
e la firma è l'hash SHA256 di quella stringa utilizzando il componente privato della chiave API.
La memorizzazione nella cache dei dati lato server può essere sempre disponibile. Ad esempio, nel nostro framework, memorizziamo nella cache le risposte a livello di SQL, non a livello di URI. Quindi l'aggiunta di questo parametro extra non rompe il meccanismo della cache.
Vedi questo articolo per alcuni dettagli sull'autenticazione RESTful nel nostro framework client / server ORM / SOA / MVC, basato su JSON e REST. Poiché consentiamo la comunicazione non solo su HTTP / 1.1, ma anche su pipe o messaggi GDI (localmente), abbiamo cercato di implementare un modello di autenticazione RESTful e non fare affidamento sulla specificità HTTP (come intestazione o cookie).
Nota successiva : l'aggiunta di una firma nell'URI può essere vista come una cattiva pratica (poiché ad esempio verrà visualizzata nei registri del server http), quindi deve essere mitigata, ad esempio da un TTL appropriato per evitare replay. Ma se i tuoi registri http sono compromessi, avrai sicuramente maggiori problemi di sicurezza.
In pratica, la prossima autenticazione di token MAC per OAuth 2.0 potrebbe essere un enorme miglioramento rispetto allo schema attuale "Concesso da token". Ma questo è ancora un lavoro in corso ed è legato alla trasmissione HTTP.
Conclusione
Vale la pena concludere che REST non è solo basato su HTTP, anche se, in pratica, è anche principalmente implementato su HTTP. REST può usare altri livelli di comunicazione. Quindi un'autenticazione RESTful non è solo un sinonimo di autenticazione HTTP, qualunque sia la risposta di Google. Non dovrebbe nemmeno usare affatto il meccanismo HTTP ma deve essere estratto dal livello di comunicazione. E se usi la comunicazione HTTP, grazie all'iniziativa Let's Encrypt non c'è motivo di non utilizzare il corretto HTTPS, necessario in aggiunta a qualsiasi schema di autenticazione.
Cookie
come un sostituto migliore per HTTP Basic Auth
te puoi fare autenticazione davvero senza stato con un metodo per scadere l'autenticazione e la possibilità di disconnettersi. Un'implementazione di esempio potrebbe utilizzare un cookie chiamato Emulated-HTTP-Basic-Auth
con un valore simile all'autent di base HTTP reale e inoltre impostare la scadenza. La disconnessione può quindi essere implementata rimuovendo quel cookie. Immagino che qualsiasi client in grado di supportare HTTP Basic Auth possa supportare anche l'autenticazione dei cookie in questo modo.
Cookie
alternativa, è possibile utilizzare un'emulazione fornita dallo stesso server per le stesse cose in un'altra intestazione ( ).
Dubito che le persone che gridano con entusiasmo "Autenticazione HTTP" abbiano mai provato a creare un'applicazione basata su browser (anziché un servizio web da macchina a macchina) con REST (nessuna offesa intesa - non credo che abbiano mai affrontato le complicazioni) .
I problemi che ho riscontrato con l'utilizzo dell'autenticazione HTTP su servizi RESTful che producono pagine HTML da visualizzare in un browser sono:
Un articolo molto approfondito che affronta questi punti per punto è qui , ma questo si traduce in un sacco di hacker javascript specifici del browser, soluzioni alternative per soluzioni alternative, eccetera. In quanto tale, inoltre, non è compatibile con le versioni successive, pertanto richiederà una manutenzione costante poiché vengono rilasciati nuovi browser. Non considero quel design pulito e chiaro, inoltre sento che c'è molto lavoro extra e mal di testa solo per poter mostrare con entusiasmo il mio badge REST ai miei amici.
Credo che i cookie siano la soluzione. Ma aspetta, i biscotti sono cattivi, vero? No, non lo sono, il modo in cui i cookie vengono spesso utilizzati è malvagio. Un cookie stesso è solo una parte delle informazioni sul lato client, proprio come le informazioni di autenticazione HTTP che il browser terrà traccia durante la navigazione. E questa informazione sul lato client viene inviata al server ad ogni richiesta, proprio come le informazioni di autenticazione HTTP. Concettualmente, l'unica differenza è che il contenuto di questo stato del lato client può essere determinato dal server come parte della sua risposta.
Rendendo le sessioni una risorsa RESTful con solo le seguenti regole:
L'unica differenza rispetto all'autenticazione HTTP, ora, è che la chiave di autenticazione viene generata dal server e inviata al client che continua a rispedirla, anziché al client che la calcola dalle credenziali immesse.
converter42 aggiunge che quando si utilizza https (cosa che dovremmo), è importante che il cookie abbia il suo flag di sicurezza impostato in modo che le informazioni di autenticazione non vengano mai inviate su una connessione non sicura. Ottimo punto, non l'avevo visto da solo.
Sento che questa è una soluzione sufficiente che funziona bene, ma devo ammettere che non sono abbastanza esperto di sicurezza per identificare potenziali buchi in questo schema - tutto quello che so è che centinaia di applicazioni Web non RESTful usano essenzialmente lo stesso protocollo di accesso ($ _SESSION in PHP, HttpSession in Java EE, ecc.). Il contenuto dell'intestazione del cookie viene semplicemente utilizzato per indirizzare una risorsa lato server, proprio come una lingua di accettazione potrebbe essere utilizzata per accedere alle risorse di traduzione, eccetera. Sento che è lo stesso, ma forse altri no? Cosa ne pensate ragazzi?
Su questo argomento si dice già abbastanza da brave persone qui. Ma ecco i miei 2 centesimi.
Esistono 2 modalità di interazione:
La macchina è il comune denominatore, espresso come API REST, e gli attori / clienti sono gli umani o le macchine.
Ora, in un'architettura veramente RESTful, il concetto di apolidia implica che tutti gli stati applicativi rilevanti (ovvero gli stati lato client) devono essere forniti con ogni richiesta. Per pertinente, si intende che tutto ciò che è richiesto dall'API REST per elaborare la richiesta e fornire una risposta appropriata.
Se lo consideriamo nel contesto di applicazioni da uomo a macchina, "basate sul browser" come sottolinea Skrebbel sopra, ciò significa che l'applicazione (web) in esecuzione nel browser dovrà inviare il suo stato e le informazioni pertinenti ad ogni richiesta rende le API REST di back-end.
Considera questo: hai una piattaforma dati / informazioni esposta asset di API REST. Forse hai una piattaforma BI self-service che gestisce tutti i cubi di dati. Ma vuoi che i tuoi clienti (umani) accedano tramite (1) app Web, (2) app mobile e (3) alcune applicazioni di terze parti. Alla fine, anche la catena di MTM porta a HTM - giusto. Pertanto, gli utenti umani rimangono all'apice della catena di informazione.
Nei primi 2 casi, hai un caso per l'interazione uomo-macchina, le informazioni vengono effettivamente consumate da un utente umano. Nell'ultimo caso, hai un programma macchina che utilizza le API REST.
Il concetto di autenticazione si applica a tutti i livelli. Come lo progetterai in modo tale che le tue API REST siano accessibili in modo uniforme e sicuro? Per come la vedo io, ci sono 2 modi:
Way-1:
Way-2:
Chiaramente, in Way-2, le API REST avranno bisogno di un modo per riconoscere e ritenere il token valido. L'API di accesso ha eseguito la verifica dell'autenticazione e pertanto la "chiave del cameriere" deve essere considerata attendibile da altre API REST nel catalogo.
Ciò, ovviamente, significa che la chiave / token di autenticazione dovrà essere archiviata e condivisa tra le API REST. Questo repository di token condiviso e attendibile può essere locale / federato qualunque, consentendo alle API REST di altre organizzazioni di fidarsi l'una dell'altra.
Ma sto divagando.
Il punto è che uno "stato" (sullo stato autenticato del client) deve essere mantenuto e condiviso in modo che tutte le API REST possano creare un cerchio di fiducia. Se non lo facciamo, che è il Way-1, dobbiamo accettare che un atto di autenticazione debba essere eseguito per qualsiasi / tutte le richieste in arrivo.
L'esecuzione dell'autenticazione è un processo che richiede molte risorse. Immagina di eseguire query SQL, per ogni richiesta in arrivo, sul tuo archivio utenti per verificare la corrispondenza uid / pwd. Oppure, per crittografare ed eseguire corrispondenze hash (stile AWS). E dal punto di vista architettonico, ogni API REST dovrà eseguire questo, sospetto, usando un comune servizio di login back-end. Perché se non lo fai, allora sporchi il codice di autorizzazione ovunque. Un gran casino.
Quindi più livelli, più latenza.
Ora, prendi Way-1 e applica a HTM. Il tuo utente (umano) si preoccupa davvero se devi inviare uid / pwd / hash o altro con ogni richiesta? No, purché non la disturbi lanciando la pagina di autenticazione / accesso ogni secondo. Buona fortuna avere clienti se lo fai. Quindi, quello che farai è archiviare le informazioni di accesso da qualche parte sul lato client, nel browser, proprio all'inizio, e inviarle con ogni richiesta fatta. Per l'utente (umano), ha già effettuato l'accesso ed è disponibile una "sessione". Ma in realtà, è autenticata su ogni richiesta.
Lo stesso con Way-2. Il tuo utente (umano) non lo noterà mai. Quindi nessun danno è stato fatto.
Che cosa succede se applichiamo Way-1 a MTM? In questo caso, dal momento che è una macchina, possiamo annoiare questo ragazzo chiedendogli di inviare informazioni di autenticazione con ogni richiesta. A nessuno importa! L'esecuzione di Way-2 su MTM non evocherà alcuna reazione speciale; è una dannata macchina. Potrebbe importare di meno!
Quindi, davvero, la domanda è cosa soddisfa le tue esigenze. L'apolidia ha un prezzo da pagare. Paga il prezzo e vai avanti. Se vuoi essere un purista, allora paga anche il prezzo e vai avanti.
Alla fine, le filosofie non contano. Ciò che conta davvero è la scoperta di informazioni, la presentazione e l'esperienza di consumo. Se le persone adorano le tue API, hai fatto il tuo lavoro.
Way-3
l'approccio ibrido. Il client accede come in Way-2
ma, come in Way-1
, le credenziali non vengono verificate rispetto a nessuno stato lato server. Indipendentemente da ciò, un token di autenticazione viene creato e inviato al client come in Way-2
. Questo token viene successivamente verificato per l'autenticità utilizzando la crittografia asimmetrica senza cercare uno stato specifico del client.
Ecco una soluzione di autenticazione veramente e completamente RESTful:
Quando un client esegue l'autenticazione:
3.1. emettere un token che contiene quanto segue:
3.2. Crittografa il token con la chiave privata.
3.3. Invia il token crittografato di nuovo all'utente.
Quando l'utente accede a qualsiasi API, deve anche passare il proprio token di autenticazione.
Questa è l'autenticazione stateless / RESTful.
Si noti che se fosse incluso un hash di password, l'utente invierebbe anche la password non crittografata insieme al token di autenticazione. Il server ha potuto verificare che la password corrispondesse alla password utilizzata per creare il token di autenticazione confrontando gli hash. Sarebbe necessaria una connessione sicura usando qualcosa come HTTPS. Javascript sul lato client potrebbe gestire il recupero della password dell'utente e la sua memorizzazione sul lato client, in memoria o in un cookie, eventualmente crittografato con la chiave pubblica del server .
Ad essere sincero con te ho visto grandi risposte qui, ma qualcosa che mi preoccupa un po 'è quando qualcuno porterà il concetto di apolide a un estremo dove diventa dogmatico. Mi ricorda quei vecchi fan di Smalltalk che volevano solo abbracciare OO puro e se qualcosa non è un oggetto, allora stai sbagliando. Dammi una pausa.
L'approccio RESTful dovrebbe semplificarti la vita e ridurre il sovraccarico e il costo delle sessioni, provare a seguirla perché è una cosa saggia da fare, ma nel momento in cui segui una disciplina (qualsiasi disciplina / linea guida) all'estremo dove essa non fornisce più il vantaggio a cui era destinato, quindi stai sbagliando. Alcuni dei migliori linguaggi oggi hanno sia la programmazione funzionale che l'orientamento agli oggetti.
Se il modo più semplice per risolvere il problema è archiviare la chiave di autenticazione in un cookie e inviarlo sull'intestazione HTTP, quindi farlo, non abusarne. Ricorda che le sessioni sono cattive quando diventano pesanti e grandi, se tutta la tua sessione è composta da una breve stringa contenente una chiave, qual è il grosso problema?
Sono aperto ad accettare correzioni nei commenti, ma non vedo il punto (finora) di rendere miserabili le nostre vite per evitare semplicemente di tenere un grande dizionario di hash nel nostro server.
In primo luogo, un servizio web RESTful è STATELESS (o in altre parole, senza sessione). Pertanto, un servizio RESTful non ha e non dovrebbe avere un concetto di sessione o cookie coinvolti. Il modo per eseguire l'autenticazione o l'autorizzazione nel servizio RESTful è utilizzare l'intestazione Autorizzazione HTTP come definito nelle specifiche HTTP RFC 2616. Ogni singola richiesta deve contenere l'intestazione di autorizzazione HTTP e la richiesta deve essere inviata tramite una connessione HTTP (SSL). Questo è il modo corretto di eseguire l'autenticazione e verificare l'autorizzazione delle richieste in un servizio Web HTTP RESTful. Ho implementato un servizio Web RESTful per l'applicazione Cisco PRIME Performance Manager presso Cisco Systems. E come parte di quel servizio web, ho implementato anche l'autenticazione / autorizzazione.
Non si tratta certamente di "chiavi di sessione" in quanto viene generalmente utilizzato per fare riferimento all'autenticazione senza sessione che viene eseguita all'interno di tutti i vincoli di REST. Ogni richiesta è auto-descrittiva e contiene informazioni sufficienti per autorizzare la richiesta da sola senza alcuno stato dell'applicazione sul lato server.
Il modo più semplice per affrontarlo è iniziare con i meccanismi di autenticazione integrati di HTTP in RFC 2617 .
L'articolo "molto penetrante" menzionato da @skrebel ( http://www.berenddeboer.net/rest/authentication.html ) discute di un metodo di autenticazione contorto ma veramente rotto.
Puoi provare a visitare la pagina (che dovrebbe essere visibile solo all'utente autenticato) http://www.berenddeboer.net/rest/site/authenticated.html senza credenziali di accesso.
(Mi dispiace non posso commentare la risposta.)
Direi che REST e autenticazione semplicemente non si mescolano. REST significa apolide ma "autenticato" è uno stato. Non puoi averli entrambi sullo stesso livello. Se sei un sostenitore di RESTful e disapprovi gli stati, allora devi andare con HTTPS (cioè lasciare il problema di sicurezza su un altro livello).
Penso che l'autenticazione riposante implichi il passaggio di un token di autenticazione come parametro nella richiesta. Esempi sono l'uso di apikeys da parte di api. Non credo che l'uso dei cookie o dell'autenticazione http sia valido.
L'approccio menzionato in precedenza è essenzialmente il tipo di concessione "Credenziali password proprietario risorsa" di OAuth2.0 . Questo è un modo semplice per iniziare. Tuttavia, con questo approccio ogni applicazione dell'organizzazione finirà con i propri meccanismi di autenticazione e autorizzazione. L'approccio raccomandato è il tipo di concessione "Codice di autorizzazione". Inoltre, nella mia risposta precedente di seguito, ho raccomandato localStorage del browser per la memorizzazione dei token di autenticazione. Tuttavia, sono arrivato a credere che i cookie siano l'opzione giusta per questo scopo. Ho dettagliato i miei motivi, l'approccio all'implementazione del tipo di concessione del codice di autorizzazione, considerazioni sulla sicurezza ecc. In questa risposta StackOverflow .
Penso che il seguente approccio possa essere utilizzato per l'autenticazione del servizio REST:
Con questo approccio stiamo eseguendo la costosa operazione di caricamento della cache con i dettagli dei diritti di accesso specifici dell'utente ogni 30 minuti. Pertanto, se un accesso viene revocato o viene concesso un nuovo accesso, sono necessari 30 minuti per riflettere o un logout seguito da un accesso.
Questo è il modo per farlo: usare OAuth 2.0 per l'accesso .
Puoi utilizzare altri metodi di autenticazione diversi da quelli di Google purché supportino OAuth.
L'uso di un'infrazione di chiave pubblica in cui la registrazione di una chiave implica un'adeguata associazione garantisce che la chiave pubblica sia vincolata all'individuo a cui è assegnata in modo da garantire il non ripudio
Vedi http://en.wikipedia.org/wiki/Public_key_infrastructure . Se si seguono gli standard PKI corretti, la persona o l'agente che utilizza in modo improprio la chiave rubata può essere identificato e bloccato. Se l'agente deve utilizzare un certificato, l'associazione diventa piuttosto stretta. Un ladro intelligente e in rapido movimento può fuggire, ma lasciano più briciole.
Per rispondere a questa domanda dalla mia comprensione ...
Un sistema di autenticazione che utilizza REST in modo da non dover effettivamente tracciare o gestire gli utenti nel tuo sistema. Questo viene fatto usando i metodi HTTP POST, GET, PUT, DELETE. Prendiamo questi 4 metodi e li consideriamo in termini di interazione con il database come CREATE, READ, UPDATE, DELETE (ma sul web usiamo POST e GET perché questo è ciò che attualmente supporta i tag di ancoraggio). Quindi trattando POST e GET come il nostro CREATE / READ / UPDATE / DELETE (CRUD), allora possiamo progettare percorsi nella nostra applicazione Web che saranno in grado di dedurre quale azione di CRUD stiamo realizzando.
Ad esempio, in un'applicazione Ruby on Rails possiamo creare la nostra app Web in modo tale che se un utente che ha effettuato l'accesso visiti http://store.com/account/logout il GET di quella pagina possa essere visualizzato come l'utente che tenta di disconnettersi . Nel nostro controller di rotaie avremmo creato un'azione che disconnettesse l'utente e lo rimandasse alla home page.
Un GET sulla pagina di accesso genererebbe un modulo. un POST sulla pagina di accesso verrebbe visualizzato come un tentativo di accesso e prendere i dati POST e usarli per accedere.
Per me, è una pratica utilizzare metodi HTTP mappati sul significato del loro database e quindi costruire un sistema di autenticazione tenendo presente che non è necessario passare da un ID di sessione o tenere traccia delle sessioni.
Sto ancora imparando: se trovi qualcosa che ho detto di essere sbagliato, per favore correggimi e se impari di più pubblicalo di nuovo qui. Grazie.
Suggerimenti validi per proteggere qualsiasi applicazione Web
Se vuoi proteggere la tua applicazione, allora dovresti assolutamente iniziare a usare HTTPS invece di HTTP , questo assicura un canale sicuro tra te e gli utenti che impedirà di annusare i dati inviati avanti e indietro agli utenti e aiuterà a conservare i dati scambiato confidenziale.
È possibile utilizzare JWT (token Web JSON) per proteggere le API RESTful , questo ha molti vantaggi rispetto alle sessioni lato server, i vantaggi sono principalmente:
1- Più scalabile, poiché i tuoi server API non dovranno mantenere sessioni per ciascun utente (il che può essere un grosso fardello quando hai molte sessioni)
2- I JWT sono autonomi e hanno i reclami che definiscono ad esempio il ruolo dell'utente e ciò a cui può accedere e rilasciare alla data e alla data di scadenza (dopo la quale JWT non sarà valido)
3- Più facile da gestire attraverso i servizi di bilanciamento del carico e se si dispone di più server API in quanto non è necessario condividere i dati della sessione né configurare il server per indirizzare la sessione allo stesso server, ogni volta che una richiesta con un JWT raggiunge qualsiasi server può essere autenticata e autorizzato
4- Meno pressione sul DB e non sarà necessario archiviare e recuperare costantemente ID sessione e dati per ogni richiesta
5- I JWT non possono essere manomessi se si utilizza una chiave avanzata per firmare il JWT, quindi è possibile fidarsi dei reclami nel JWT inviati con la richiesta senza dover controllare la sessione dell'utente e se è autorizzato o meno , puoi semplicemente controllare JWT e sei pronto a sapere chi e cosa può fare questo utente.
Molte librerie offrono modi semplici per creare e validare JWT nella maggior parte dei linguaggi di programmazione, ad esempio: in node.js uno dei più popolari è jsonwebtoken
Poiché le API REST generalmente mirano a mantenere il server senza stato, quindi i JWT sono più compatibili con quel concetto in quanto ogni richiesta viene inviata con token di autorizzazione autonomo (JWT) senza che il server debba tenere traccia della sessione dell'utente rispetto alle sessioni che rendono il server stateful in modo che ricordi l'utente e il suo ruolo, tuttavia, le sessioni sono anche ampiamente utilizzate e hanno i loro pro, che puoi cercare se vuoi.
Una cosa importante da notare è che devi consegnare in modo sicuro il JWT al client usando HTTPS e salvarlo in un luogo sicuro (ad esempio nella memoria locale).
Puoi saperne di più sui JWT da questo link