Cos'è un JWT?
JWT sta per JSON Web Token, definito dallo standard RFC 7519. È una stringa compatta e auto-contenuta che codifica informazioni (detti "claim") in modo verificabile e opzionalmente cifrato. Il caso d'uso più comune è l'autenticazione: dopo il login, il server emette un JWT che il client allega a ogni richiesta successiva.
La caratteristica chiave di JWT è l'essere stateless: il server non deve consultare un database di sessioni per verificare l'identità — verifica solo la firma matematica del token.
La struttura di un JWT
Un JWT è composto da tre parti separate da un punto (.), ognuna codificata in Base64URL:
1. Header
Contiene il tipo di token (JWT) e l'algoritmo usato per la firma. Decodificato in JSON:
2. Payload (i "claim")
Contiene le informazioni sull'utente e sul token. I claim standard (definiti da RFC 7519) includono:
⚠️ Il payload NON è cifrato! È solo codificato in Base64URL — chiunque può leggerlo. Non mettere mai password, chiavi API o dati sensibili nel payload JWT.
3. Signature
È la garanzia di integrità. Viene calcolata così:
Se qualcuno modifica anche solo un carattere del payload, la firma non corrisponderà più e il server rifiuterà il token. Non puoi falsificare un JWT senza conoscere la chiave segreta.
Il flusso di autenticazione JWT
- Login: il client invia username e password al server
- Verifica credenziali: il server autentica l'utente
- Emissione token: il server firma un JWT con la chiave segreta e lo invia al client
- Richieste successive: il client allega il JWT nell'header
Authorization: Bearer <token> - Verifica stateless: il server verifica la firma — senza query al database
Access token e Refresh token
Il punto debole di JWT è la revoca: un token valido rimane valido fino alla scadenza anche se l'utente fa logout. La soluzione standard è il pattern access + refresh token:
- Access token: JWT con scadenza breve (5–15 minuti). Viene allegato a ogni richiesta. Se rubato, espira presto.
- Refresh token: stringa opaca lunga, salvata in DB, scadenza lunga (7–30 giorni). Usata solo per ottenere un nuovo access token. Può essere revocata (eliminata dal DB).
Algoritmi di firma: HS256 vs RS256 vs ES256
HS256 — HMAC-SHA256
- Chiave simmetrica (stessa per firma e verifica)
- Semplice da implementare
- Veloce
- Tutti i servizi devono condividere il segreto
- Ideale: monoliti, microservizi interni
RS256 — RSA-SHA256
- Coppia di chiavi asimmetrica
- Chiave privata: solo il server di auth firma
- Chiave pubblica: qualsiasi servizio verifica
- Più lento di HS256
- Ideale: architetture a microservizi, OAuth 2.0
ES256 — ECDSA
- Asimmetrico come RS256
- Firma molto più corta (256 bit vs 2048 RSA)
- Più veloce di RS256
- Ideale: mobile, IoT, performance critiche
⚠️ Algoritmo "none"
- Nessuna firma — token non verificato
- Mai usare in produzione
- Alcuni parser vulnerabili accettano "alg: none"
- Verifica sempre che il tuo backend lo rifiuti
Dove salvare il JWT nel browser?
Questa è una delle domande più dibattute nello sviluppo web. Le opzioni:
- localStorage / sessionStorage: facile da usare, ma accessibile da JavaScript → vulnerabile a attacchi XSS. Da evitare per token sensibili.
- Cookie HttpOnly + Secure + SameSite=Strict: non accessibile da JS, inviato automaticamente dal browser, protetto da CSRF con SameSite. La scelta più sicura per la maggior parte dei casi.
- Memoria (variabile JS): immune da XSS e persistenza, ma il token va perduto al refresh della pagina — richiede meccanismo di rinnovo silenzioso.
Best practice moderna: access token in memoria, refresh token in cookie HttpOnly. Il refresh avviene in modo silenzioso quando l'access token scade, usando il refresh token dal cookie.
Quando NON usare JWT
JWT è spesso usato dove non serve. Considera alternative quando:
- Hai bisogno di invalidare sessioni istantaneamente: un session token in DB è più adatto — JWT non può essere revocato senza infrastruttura aggiuntiva
- Le sessioni durano ore o giorni senza rinnovo: un access token con scadenza lunga è un rischio
- L'applicazione è server-rendered (SSR) tradizionale: i cookie di sessione sono più semplici e sicuri
- Il payload è grande: JWT invia i dati utente a ogni richiesta — se il payload è 2KB, moltiplica per migliaia di richieste al secondo
FAQ
No. I session token sono opachi — il server mantiene lo stato in memoria o database. I JWT sono auto-contenuti: il server non tiene stato, verifica solo la firma. JWT è stateless, il session token è stateful.
Non nativamente. Le soluzioni sono: access token con scadenza breve (5–15 min) + refresh token revocabile in DB, oppure una blocklist dei token revocati (aggiunge stato ma rimane selettivo). La prima è la più usata.
HS256 (simmetrico) è più semplice e veloce ma richiede di condividere il segreto tra tutti i servizi. RS256 (asimmetrico) è preferibile quando più servizi devono verificare i token senza poterli emettere — tipico nei microservizi.
I cookie HttpOnly + Secure + SameSite=Strict sono la scelta più sicura: non accessibili da JavaScript e protetti da CSRF con SameSite. localStorage è pratico ma vulnerabile a XSS. La best practice moderna è access token in memoria + refresh token in cookie HttpOnly.