Scopri cos'è un JWT (JSON Web Token), come funzionano le sue tre parti, dove si usa e i consigli di sicurezza per evitare gli errori più comuni con i token.

Un JWT (JSON Web Token) è una stringa compatta e sicura per gli URL che rappresenta un insieme di informazioni (di solito su un utente o una sessione) in modo che possa essere trasferita tra sistemi. Lo vedrai spesso come un valore lungo che inizia con qualcosa come eyJ..., inviato in un header HTTP come Authorization: Bearer <token>.
I login tradizionali spesso si basano su sessioni server-side: dopo il login, il server conserva i dati di sessione e fornisce al browser un cookie con l'ID di sessione. Ogni richiesta include quel cookie e il server recupera la sessione.
Con l'autenticazione basata su token, il server può evitare di mantenere lo stato di sessione per ogni utente. Il client conserva un token (come un JWT) e lo include nelle chiamate API. Questo è popolare per le API perché:
Sfumatura importante: “stateless” non significa “mai più controlli lato server”. Molti sistemi reali validano ancora i token rispetto allo stato dell'utente, alla rotazione delle chiavi o a meccanismi di revoca.
I JWT spesso contengono prova di autenticazione (sei autenticato) e indizi di autorizzazione (ruoli, permessi, scope), ma il server dovrebbe comunque far rispettare le regole di autorizzazione.
Vedrai comunemente i JWT usati come access token in:
Un JWT è una stringa compatta composta da tre parti, ciascuna codificata in Base64URL e separate da punti:
header.payload.signature
Esempio (redatto):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNzAwMDAwMDAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c…
L'header descrive come è stato creato il token—soprattutto l'algoritmo di firma (es. HS256, RS256/ES256) e il tipo di token.
Campi comuni:
typ: spesso "JWT" (spesso ignorato nella pratica)alg: l'algoritmo di firma usatokid: un identificatore della chiave per aiutare il verificatore a scegliere la chiave corretta durante la rotazioneNota di sicurezza: non fidarti ciecamente dell'header. Applica una allowlist degli algoritmi che effettivamente usi e non accettare alg: "none".
Il payload contiene i “claim” (campi) sull'utente e sul contesto del token: per chi è, chi lo ha emesso e quando scade.
Importante: i JWT non sono criptati di default. La codifica Base64URL rende il token sicuro per gli URL; non nasconde i dati. Chiunque ottenga il token può decodificare header e payload.
Per questo motivo evita di mettere segreti (password, API key) o dati personali sensibili in un JWT.
La signature è creata firmando header + payload:
La signature fornisce integrità: permette al server di verificare che il token non sia stato modificato e che sia stato emesso da un signer di fiducia. Non fornisce confidenzialità.
Dal momento che un JWT include header e payload in ogni richiesta in cui viene inviato, token più grandi significano più larghezza di banda e overhead. Mantieni i claim leggeri e preferisci identificatori a dati ingombranti.
I claim solitamente rientrano in due categorie: registered (nomi standardizzati) e custom (campi della tua app).
iss (issuer): chi ha creato il tokensub (subject): di chi parla il token (spesso un user ID)aud (audience): per chi è destinato il token (es. una specifica API)exp (expiration time): quando il token non deve più essere accettatoiat (issued at): quando è stato emesso il tokennbf (not before): il token non deve essere accettato prima di questo istanteIncludi solo ciò di cui il servizio ricevente ha davvero bisogno per decidere l'autorizzazione.
Esempi buoni:
user_id)Evita “claim di convenienza” che duplicano molti dati di profilo. Ingrandiscono il token, diventano rapidamente obsoleti e aumentano l'impatto in caso di perdita.
Poiché il payload è leggibile, non inserire:
Se ti servono informazioni sensibili, conservale lato server e metti solo un riferimento (come un ID) nel token—or usa un formato token cifrato (JWE) quando appropriato.
Firmare non è criptare.
Quando un JWT viene emesso, il server firma l'header e il payload codificati. Quando il token viene presentato successivamente, il server ricalcola la signature e la confronta. Se qualcuno cambia anche un solo carattere (es. "role":"user" a "role":"admin"), la verifica fallisce e il token viene rifiutato.
JWT è un formato di token. OAuth 2.0 e OpenID Connect (OIDC) sono protocolli che descrivono come le app richiedono, emettono e usano i token.
OAuth 2.0 riguarda principalmente l'autorizzazione: permettere a un'app di accedere a un'API per conto di un utente senza condividere la password dell'utente.
Gli access token sono tipicamente a breve durata (minuti). Durate brevi limitano i danni in caso di fuga.
OIDC aggiunge l'autenticazione (chi è l'utente) sopra OAuth 2.0 e introduce un ID token, che di solito è un JWT.
Regola chiave: non usare un ID token per chiamare un'API.
Se vuoi più contesto su flussi pratici, vedi /blog/jwt-authentication-flow.
Un flusso tipico è così:
L'utente effettua il login (email/password, SSO, ecc.). Se ha successo, il server crea un JWT (spesso un access token) con claim essenziali come subject e scadenza.
Il server firma il token e lo restituisce al client (web app, app mobile o altro servizio).
Per endpoint protetti, il client include il JWT nell'header Authorization:
Authorization: Bearer <JWT>
Prima di servire la richiesta, l'API in genere controlla:
exp (non scaduto)iss (issuer atteso)aud (destinato a questa API)Se tutti i controlli passano, l'API considera l'utente autenticato e applica le regole di autorizzazione (es. permessi a livello di record).
Poiché gli orologi dei sistemi possono scostarsi, molti sistemi consentono un piccolo clock skew quando validano claim temporali come exp (e talvolta nbf). Mantieni lo skew piccolo per evitare di estendere la validità del token più del previsto.
La scelta dello storage cambia cosa possono rubare gli attaccanti e quanto facilmente possono ripetere l'uso di un token.
Conservazione in memoria (spesso raccomandata per le SPA) mantiene l'access token nello stato JS. Si cancella al refresh e riduce il rischio di furto “a posteriori”, ma un bug XSS può comunque leggerlo mentre la pagina è in esecuzione. Associalo a token a breve durata e a un flusso di refresh.
localStorage/sessionStorage sono facili ma rischiosi: qualsiasi vulnerabilità XSS può esfiltrare i token dallo storage web. Se li usi, rendi la prevenzione XSS non negoziabile (CSP, escaping dell'output, cura delle dipendenze) e mantieni i token a breve durata.
Cookie sicuri (spesso la scelta più sicura per il web) memorizzano i token in cookie HttpOnly così JavaScript non può leggerli—riducendo l'impatto del furto via XSS. Lo svantaggio è il rischio CSRF, poiché i browser inviano i cookie automaticamente.
Se usi cookie, imposta:
HttpOnlySecure (solo HTTPS)SameSite=Lax o SameSite=Strict (alcuni flussi cross-site potrebbero richiedere SameSite=None; Secure)Considera anche token CSRF per le richieste che modificano lo stato.
Su iOS/Android, conserva i token nello storage sicuro della piattaforma (Keychain / Keystore-backed storage). Evita file in chiaro o preferenze. Se nel tuo threat model ci sono dispositivi con root/jailbreak, assumi l'estrazione possibile e fai affidamento su token a breve durata e controlli server-side.
Limita cosa può fare un token: usa scope/claim minimi, mantieni gli access token a breve durata e evita di incorporare dati sensibili.
I JWT sono comodi, ma molti incidenti derivano da errori prevedibili. Tratta un JWT come denaro contante: chi lo ottiene spesso può spenderlo.
Se un token dura giorni o settimane, una fuga dà all'attaccante quell'intervallo di tempo.
Preferisci access token a breve durata (minuti) e rinnovali tramite un meccanismo più sicuro. Se ti serve il “ricordami”, implementalo con refresh token e controlli server-side.
Una firma valida non basta. Verifica iss e aud, e valida claim temporali come exp e nbf.
Decodificare non è verificare. Verifica sempre la signature sul server e applica l'autorizzazione lato server.
Evita di mettere JWT nei parametri di query. Possono finire nella cronologia del browser, nei log server, negli strumenti di analytics e negli header referrer.
Usa Authorization: Bearer ... invece.
Assumi che chiavi e token possano fuoriuscire. Ruota le chiavi di firma, usa kid per supportare una rotazione fluida e prevedi una strategia di revoca (scadenze brevi + possibilità di disabilitare account/sessioni). Per linee guida sullo storage, vedi /blog/where-to-store-jwts-safely.
I JWT sono utili, ma non sono automaticamente la scelta migliore. La vera domanda è se benefici di un token auto-contenuto che può essere verificato senza una lookup su database a ogni richiesta.
Per app web tradizionali server-rendered dove l'invalidazione è importante, sessioni server-side con cookie HttpOnly sono spesso il default più semplice e sicuro.
Scegli JWT se hai bisogno di verifica stateless tra servizi e puoi mantenere i token a breve durata.
Evita JWT se ti serve revoca immediata, prevedi di mettere dati sensibili nel token o puoi usare cookie di sessione senza attriti.
Verifica con la chiave corretta e l'algoritmo atteso. Rifiuta firme invalide—niente eccezioni.
exp (expiration)Assicurati che il token non sia scaduto.
nbf (not before)Se presente, assicurati che il token non venga usato troppo presto.
aud (audience)Conferma che il token fosse destinato alla tua API/servizio.
iss (issuer)Conferma che il token provenga dall'issuer atteso.
Valida il formato del token, imponi una dimensione massima e rifiuta tipi di claim inaspettati per ridurre bug ai margini.
HS256 (chiave simmetrica): un secret condiviso firma e verifica.
RS256 / ES256 (chiavi asimmetriche): la chiave privata firma; la chiave pubblica verifica.
Regola pratica: se più sistemi indipendenti devono verificare i token (o non ti fidi pienamente di ogni verificatore), preferisci RS256/ES256.
iss, aud, e un user ID solo se la policy lo consente).Il JWT è cifrato?
Non di default. La maggior parte dei JWT è firmata, non cifrata, quindi il contenuto può essere letto da chiunque abbia il token. Usa JWE o tieni i dati sensibili fuori dai JWT.
Posso revocare un JWT?
Non facilmente se ti affidi solo ad access token auto-contenuti. Approcci comuni includono token a breve durata, deny-list per eventi ad alto rischio o refresh token con rotazione.
Quanto dovrebbe durare exp?
Più breve possibile compatibilmente con UX e architettura. Molte API usano minuti per gli access token, abbinandoli a refresh token per sessioni più lunghe.
Se stai implementando l'autenticazione JWT in una nuova API o SPA, gran parte del lavoro è ripetitivo: collegare middleware, validare iss/aud/exp, impostare i flag dei cookie e tenere la gestione dei token fuori dai log.
Con Koder.ai, puoi generare codice per una web app (React), servizi backend (Go + PostgreSQL) o un'app mobile Flutter tramite un workflow guidato in chat—poi iterare in una planning mode, usare snapshot e rollback mentre affini la sicurezza e esportare il codice sorgente quando sei pronto. È un modo pratico per accelerare la costruzione dei flussi di autenticazione basati su JWT mantenendo il controllo sulla logica di verifica, la strategia di rotazione delle chiavi e le impostazioni di deployment/hosting (inclusi domini personalizzati).
Un JWT (JSON Web Token) è una stringa compatta e sicura per gli URL che trasporta claim (campi di dati) e può essere verificata da un server. Viene comunemente inviato nelle richieste API tramite:
Authorization: Bearer <token>L'idea chiave: il server può validare l'integrità del token (tramite la firma) senza dover mantenere un record di sessione per ogni richiesta.
L'autenticazione basata su sessione tipicamente memorizza lo stato sul server (un record di sessione indicizzato da un cookie o un ID di sessione). Con l'autenticazione tramite JWT, il client presenta a ogni richiesta un token firmato che l'API valida.
I JWT sono popolari per le API e le architetture multi-servizio perché la verifica può avvenire localmente, riducendo la necessità di uno storage di sessione condiviso.
“Stateless” spesso include comunque controlli server-side come deny-list di revoca, controlli sullo stato utente o rotazione delle chiavi.
Un JWT è composto da tre parti codificate in Base64URL separate da punti:
header.payload.signatureL'header descrive come è stato firmato, il payload contiene i claim (come sub, exp, aud) e la signature permette al server di rilevare manomissioni.
No. I JWT standard sono di solito firmati, non criptati.
Se serve riservatezza, considera JWE (token criptati) o conserva i dati sensibili lato server e metti solo un identificatore nel JWT.
La firma permette al server di verificare che il token non sia stato alterato e che sia stato emesso da chi possiede la chiave di firma.
Non garantisce invece:
expTratta il token come una credenziale: se viene compromesso, spesso può essere riutilizzato fino alla scadenza.
alg indica quale algoritmo è stato usato (es. HS256 vs RS256). kid è un identificatore della chiave che aiuta a selezionare la chiave corretta durante la rotazione.
Regole pratiche di sicurezza:
Inizia con i claim registrati standard e mantieni i custom al minimo.
Claim comuni registrati:
JWT è un formato di token; OAuth 2.0 e OpenID Connect sono protocolli.
Mappatura tipica:
Per le app browser, le opzioni comuni sono:
localStorage/: comodi, ma qualsiasi XSS può esfiltrarli. Se li usi, rendi la prevenzione XSS non negoziabile (CSP, escaping dell'output, cura delle dipendenze) e mantieni i token brevi.Al minimo, valida:
exp (non scaduto)iss (issuer atteso)aud (destinato alla tua API)nbf (se presente)Aggiungi anche protezioni pratiche:
alg arbitrari.alg: "none".kid non attendibile causi comportamenti di lookup della chiave non sicuri.iss (issuer)sub (subject / identificatore utente)aud (audience / API di destinazione)exp (expiration)iat (issued at)nbf (not before)Evita di inserire segreti o dati personali sensibili nel payload, poiché sono leggibili se il token viene esposto.
Importante: non usare un ID token per chiamare un'API solo perché “somiglia” a un access token JWT.
sessionStorageSameSite + token CSRF per richieste di modifica dello stato).Qualunque scelta tu faccia, mantieni gli access token a breve durata e limita i privilegi del token.