Autenticazione: utilizzo JWT vs sessione


122

Qual è il vantaggio di utilizzare JWT rispetto alle sessioni in situazioni come l'autenticazione?

Viene utilizzato come approccio autonomo o viene utilizzato nella sessione?

Risposte:


213

JWT non ha alcun vantaggio rispetto all'utilizzo di "sessioni" per dire. I JWT forniscono un mezzo per mantenere lo stato della sessione sul client invece di farlo sul server.

Ciò che le persone spesso intendono quando chiedono questo è "Quali sono i vantaggi dell'utilizzo di JWT rispetto all'utilizzo di sessioni lato server "

Con le sessioni lato server dovrai o memorizzare l'identificatore di sessione in un database, oppure tenerlo in memoria e assicurarti che il client raggiunga sempre lo stesso server. Entrambi hanno degli svantaggi. Nel caso del database (o di un altro archivio centralizzato), questo diventa un collo di bottiglia e una cosa da mantenere - essenzialmente una query extra da eseguire con ogni richiesta.

Con una soluzione in-memory limiti il ​​ridimensionamento orizzontale e le sessioni saranno influenzate da problemi di rete (client in roaming tra Wi-Fi e dati mobili, riavvio dei server, ecc.)

Spostare la sessione sul client significa rimuovere la dipendenza da una sessione lato server, ma impone una propria serie di sfide.

  • Conservare il token in modo sicuro
  • trasportandolo in modo sicuro
  • Le sessioni JWT a volte possono essere difficili da invalidare.
  • Fidarsi del reclamo del cliente.

Questi problemi sono condivisi da JWT e altri meccanismi di sessione lato client allo stesso modo.

JWT in particolare affronta l'ultimo di questi. Può aiutare a capire cos'è un JWT:

È un po 'di informazione. Per le sessioni utente puoi includere il nome utente e l'ora in cui scade il token. Ma potrebbe plausibilmente essere qualsiasi cosa, anche l'ID di sessione o l'intero profilo dell'utente. (Per favore, non farlo però) Ha una firma sicura che impedisce a soggetti malintenzionati di generare token falsi (è necessario accedere alla chiave privata del server per firmarli e puoi verificare che non siano stati modificati dopo che sono stati firmati) inviarli ad ogni richiesta, proprio come Authorizationverrebbe inviato un cookie o un Header. In effetti sono comunemente inviati nell'intestazione HTTP Authorization, ma anche l'uso di un cookie va bene.

Il token è firmato e quindi il server può verificarne l'origine. Daremo per scontato che il server si fidi della propria capacità di firmare in modo sicuro (è necessario utilizzare una libreria standard: non provare a farlo da soli e proteggere adeguatamente il server)

Per quanto riguarda il trasporto sicuro del token, la risposta è generalmente quella di inviarlo tramite un canale crittografato, solitamente httpS.

Per quanto riguarda l'archiviazione sicura del token nel client, è necessario assicurarsi che i malintenzionati non possano accedervi. Questo (principalmente) significa impedire a JS di siti Web dannosi di leggere il token per rispedirglielo. Ciò viene mitigato utilizzando le stesse strategie utilizzate per mitigare altri tipi di attacchi XSS.

Se hai bisogno di invalidare i JWT, ci sono sicuramente modi in cui questo può essere ottenuto. Memorizzare un'epoca per utente solo per gli utenti che hanno richiesto di "terminare le altre sessioni" è un metodo molto efficiente che probabilmente sarà abbastanza buono. Se un'applicazione richiede l'invalidazione per sessione, è possibile mantenere un ID sessione nello stesso modo e la tabella "token interrotti" può ancora essere mantenuta in modo che sia molto più piccola della tabella utente completa (è sufficiente conservare i record più recenti la durata massima consentita del token.) Quindi la capacità di invalidare il token nega parzialmente il vantaggio delle sessioni lato client in quanto si dovrebbe mantenere lo stato di interruzione della sessione. Questa sarà molto probabilmente una tabella molto più piccola della tabella dello stato della sessione originale, quindi le ricerche sono comunque più efficienti.

Un altro vantaggio dell'utilizzo dei token JWT è che è ragionevolmente facile da implementare utilizzando le librerie disponibili probabilmente in ogni lingua che ci si può aspettare di avere. Inoltre è completamente separato dallo schema di autenticazione dell'utente iniziale: se si passa a un sistema basato sulle impronte digitali non è necessario apportare modifiche allo schema di gestione della sessione.

Un vantaggio più sottile: poiché il JWT può trasportare "informazioni" e questo è accessibile dal cliente, ora puoi iniziare a fare alcune cose intelligenti. Ad esempio, ricorda all'utente che la sua sessione scadrà alcuni giorni prima che venga disconnesso, dando loro la possibilità di autenticarsi nuovamente, in base alla data di scadenza nel token. Qualunque cosa tu possa immaginare.

Quindi, in breve: JWT risponde ad alcune delle domande e dei difetti di altre tecniche di sessione.

  1. Autenticazione "più economica" perché è possibile eliminare un round trip del DB (o almeno avere una tabella molto più piccola da interrogare!), Che a sua volta abilita la scalabilità orizzontale.
  2. Reclami lato client a prova di manomissione.

Sebbene i JWT non rispondano ad altri problemi come l'archiviazione o il trasporto sicuri, non introduce nuovi problemi di sicurezza.

Esiste molta negatività intorno ai JWT, ma se implementi la stessa sicurezza che faresti per altri tipi di autenticazione, starai bene.

Un'ultima nota: non è nemmeno Cookie vs Tokens. I cookie sono un meccanismo per archiviare e trasportare bit di informazioni e possono essere utilizzati anche per archiviare e trasportare token JWT.


4
Vale la pena notare che le sessioni lato server non devono memorizzare alcuna informazione sul server. Il server può utilizzare il client come negozio allo stesso modo del JWT. La vera differenza sta in 1) evitare le regole di sicurezza del browser passando il valore come intestazione della richiesta diversa dall'intestazione del cookie e 2) avere un formato standardizzato con JWT.
Xeoncross

1
Diresti che è sicuro memorizzare un jwt nella memoria locale? In caso contrario, dov'è un posto sicuro per salvarlo in modo che l'utente rimanga connesso?
Jessica,

1
Sì, localstorage è generalmente il posto più corretto per archiviarlo lato client. Devi avere a che fare con XSS - Non sono un esperto di programmazione web, ma guarda questa risposta stackoverflow.com/a/40376819/1810447 e cerca "How To Protect Against XSS"
The Tahaan

1
Nel tuo commento non parli di soluzione basata su cache + token di sessione. Mi suona "meglio" della tabella "token uccisi" di JWT +, perché con questa tabella "token uccisi", hai comunque bisogno di un accesso al DB, che avrai anche con sessioni + cache (anche questo piccolo). E persistere JWT è più doloroso da implementare rispetto alle sessioni persistenti, perché devi giocare con un refresh_token (quindi due token da mantenere) ... Qualsiasi commento sarebbe davvero apprezzato ... soprattutto se hai un numero per mostrare come JWT + kill_table è più efficiente di sessioni + cache ;-)
tobiasBora

2
@TheTahaan localStorage non è consigliato per archiviare JWT. Anche il link che hai condiviso lo menziona. Questo blog ha una buona spiegazione del motivo per cui JWT non dovrebbe essere archiviato in localStorage.
Harke

40

La risposta breve è: nessuna.

Una versione più lunga è:

Ho implementato JWT per la gestione delle sessioni dopo aver letto questa raccomandazione nei documenti di GraphQL :

Se non hai familiarità con nessuno di questi meccanismi di autenticazione, ti consigliamo di utilizzare express-jwt perché è semplice senza sacrificare alcuna flessibilità futura.

L'implementazione è stata davvero semplice in quanto ha aggiunto solo un po 'di complessità. Dopo un po ', però, io (come te) ho iniziato a chiedermi quali fossero i vantaggi. Risulta che ce ne sono pochissimi (o forse nessuno) per JWT per quanto riguarda la gestione delle sessioni, come spiega in dettaglio questo post del blog:

Smetti di usare JWT per le sessioni


0

I miei due centesimi, che in arrivo aggiungono un po 'di contrasto al famoso post sul blog di joepie91.

Considerando che le applicazioni di oggi (e di domani) sono (per lo più) native del cloud
C'è un vantaggio economico nell'autenticazione JWT stateless , che scala man mano che l'applicazione scala: le
applicazioni cloud comportano costi insieme a ogni respiro che si ricava .
Questo costo viene ridotto quando gli utenti non devono più autenticarsi "con" un archivio sessioni.

Elaborazione L'
esecuzione di un session store 24 ore su 24, 7 giorni su 7 costa denaro.
Non puoi farla franca con soluzioni basate sulla memoria nel mondo di K8S, poiché i pod sono effimeri.
Le sessioni appiccicose non andranno bene per lo stesso identico motivo.


Archiviazione L' archiviazione dei dati costa denaro. archiviare i dati in un SSD costa ancora di più.
Le operazioni relative alla sessione devono essere risolte rapidamente, quindi un'unità ottica non è un'opzione.

I / O
Alcuni provider di servizi cloud addebitano denaro per l'I / O relativo al disco.

Larghezza di banda
Alcuni provider di servizi cloud fanno pagare per l'attività di rete tra le istanze del server.
Ciò si applica poiché è quasi certo che l'API e il session store siano istanze separate.

Clustering del session store
Il costo aumenta ulteriormente tutti i costi sopra menzionati.


"Non puoi farla franca con soluzioni basate sulla memoria nel mondo di K8S, poiché i pod sono effimeri" Non sono sicuro di cosa intendi con questo. Redis funziona sicuramente in un ambiente K8S e un pod Redis che non funziona abbastanza frequentemente da influire sugli utenti sembra molto improbabile.
quietContest

@quietContest Personalmente preferisco non avere a che fare con la probabilità durante la creazione del software. A parte la stabilità della soluzione, un attacco può causare il malfunzionamento del software e il riavvio dei pod, il che comporterebbe la perdita della sessione. Per questo motivo opterei per una soluzione basata su JWT.
Eyal Perry,

1
"Personalmente preferisco non avere a che fare con la probabilità quando creo software". Penso che lo preferiremmo tutti, motivo per cui non dovremmo progettare sistemi che si basano su archivi di dati in memoria che non falliscono mai, perché la probabilità che ciò avvenga sembra ragionevolmente alta. Per quanto riguarda l'altro punto, se hai un attaccante che è in grado di chiudere costantemente la tua istanza redis, la soluzione a questo probabilmente non deve coinvolgere l'uso di JWT.
quietContest

@quietContest in modo coerente o un evento che capita una volta nella vita sono gli stessi per me in questo aspetto. ad esempio, un attacco DDoS ben piazzato può far sì che il server "disconnetta gli utenti". Questo non va bene per la reputazione di affidabilità del software. Penso che redis sia comunque eccessivo per la gestione della sessione. Costa e deve essere ridimensionato, mentre la memorizzazione (sicura) di un JWT in un cookie non lo fa.
Eyal Perry

1
@quietContest, grazie per il tuo contributo, adoro la discussione!
Eyal Perry

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.