Tools Blog

Cos'è un JWT? Comprensione dei token Web JSON e dell'autenticazione stateless

JSON Web Tokens Architecture

Quando accedi a una moderna applicazione a pagina singola (come React o Vue) o a un'app mobile, il server ha bisogno di un modo per ricordare chi sei. Tradizionalmente, lo faceva memorizzando un "ID di sessione" in un enorme database sul server e rilasciando un cookie sul tuo browser. Ogni volta che si faceva clic su un pulsante, il server doveva cercare quell'ID nel suo database. Questa è chiamata autenticazione con stato.

Tuttavia, nell’era dei microservizi e della scalabilità del cloud, i database sono diventati un collo di bottiglia. Per risolvere questo problema, gli sviluppatori hanno adottato l'autenticazione senza stato tramite JSON Web Tokens (JWT). Con JWT, il server non ha bisogno di ricordare chi sei: il tuo browser dice al server esattamente chi sei e utilizza la crittografia per dimostrarlo.

🎥 Video didattico: come funziona la crittografia JWT (Segnaposto per il tutorial concettuale di YouTube incorporato)

L'anatomia di un JWT

Se controlli il traffico di rete dopo aver effettuato l'accesso a un'app moderna, probabilmente vedrai un'intestazione "Autorizzazione: portatore" seguita da una lunga stringa di caratteri dall'aspetto casuale separata da due punti. Questo è un JWT.

Un JWT è composto esattamente da tre parti: Header.Payload.Signature.

1. L'intestazione

La prima parte è un oggetto JSON con codifica Base64URL che descrive semplicemente il token. Di solito contiene due proprietà: il tipo di token (JWT) e l'algoritmo di firma utilizzato (come HMAC SHA256 o RSA).

2. Il carico utile (reclami)

Anche la parte centrale è un oggetto JSON con codifica Base64URL. È qui che risiedono i dati reali. Questi dati sono chiamati "claims". Ad esempio, potrebbe contenere il tuo ID utente, il tuo ruolo (ad esempio "Amministratore") e un timestamp di scadenza. Poiché questo carico utile è allegato a ogni richiesta, il server sa immediatamente chi sei senza interrogare un database.

AVVISO CRITICO: il payload è semplicemente codificato, non crittografato. Chiunque intercetti un JWT può facilmente decodificarlo e leggere il carico utile. Non archiviare mai password, numeri di previdenza sociale o dati sensibili all'interno di un payload JWT.

3. La firma

Se chiunque può leggere e modificare il payload, cosa impedisce a un utente malintenzionato di modificare il proprio ruolo da "Utente" ad "Amministratore"? La risposta è la firma.

Per creare la firma, il server prende l'intestazione, il payload e una chiave segreta altamente sicura (nota solo al server) e li esegue attraverso un algoritmo crittografico (come SHA256). L'hash risultante diventa la firma.

Quando il server riceve un token dal client, ricalcola la firma utilizzando la sua chiave segreta. Se l'utente ha manomesso il payload (anche modificando una singola lettera), la firma ricalcolata non corrisponderà alla firma sul token e il server rifiuterà immediatamente la richiesta come fraudolenta.

Ispeziona i token in sicurezza

Hai bisogno di leggere il payload di un JWT per eseguire il debug della tua applicazione? Utilizza il nostro decodificatore JWT offline per ispezionare istantaneamente le richieste senza inviare il tuo token sensibile a un server remoto.

Apri il decodificatore JWT

Perché i microservizi adorano i JWT

Immagina un'azienda come Netflix. Hanno un server di autenticazione, un server di streaming video e un server di fatturazione. Se utilizzassero sessioni tradizionali, ogni singolo server dovrebbe comunicare costantemente con un database centrale per verificare se un utente ha effettuato l’accesso.

Con i JWT, il server di autenticazione firma il token utilizzando una chiave privata. L'utente passa quindi il token direttamente al server video. Poiché il server video dispone della chiave pubblica, può verificare in modo indipendente la firma. Il server video sa esattamente chi è l'utente senza mai parlare con il server di autenticazione o con un database. Ciò consente all’infrastruttura di scalare all’infinito senza colli di bottiglia.

Il lato oscuro: invalidazione dei token

I JWT non sono perfetti. La loro più grande forza (essere apolidi) è anche la loro più grande debolezza. Poiché il server non conserva un registro dei token attivi, non è possibile disconnettere facilmente un utente o invalidare un token specifico prima che scada.

Se un hacker ruba il JWT di un utente, l'hacker avrà pieno accesso fino allo scadere del timestamp di scadenza del token. Per mitigare questo rischio, gli ingegneri della sicurezza utilizzano un sistema a due token:

  • Token di accesso: JWT di breve durata (ad esempio 15 minuti) utilizzati per le richieste API.
  • Token di aggiornamento: token con stato di lunga durata archiviati in modo sicuro, utilizzati rigorosamente per richiedere nuovi token di accesso. Se un account viene compromesso, il server revoca il token di aggiornamento e il token di accesso dell'hacker morirà naturalmente entro 15 minuti.

Domande frequenti (FAQ)

Dove dovrei memorizzare un JWT sul frontend?

La memorizzazione dei JWT in localStorage li rende vulnerabili agli attacchi Cross-Site Scripting (XSS). Il posto più sicuro in cui memorizzare un JWT in un browser web è all'interno di un cookie HttpOnly, che impedisce a JavaScript di accedervi.

Cosa succede se la chiave segreta del mio server viene divulgata?

Catastrofe. Se un hacker ottiene la chiave segreta HMAC o la chiave privata RSA, può generare JWT validi con qualsiasi payload desideri. Potrebbero creare token concedendosi i privilegi di "Super Admin" e il tuo server li accetterebbe come validi. È necessario ruotare immediatamente le chiavi.

I JWT sono più veloci dei cookie di sessione?

Non necessariamente. I JWT hanno dimensioni di file significativamente maggiori rispetto a un ID di sessione di 32 caratteri, il che significa che consumano più larghezza di banda di rete per ogni richiesta. Il loro vantaggio in termini di velocità deriva interamente dal bypassare le ricerche nel database sul backend.