6 min

Cos'è un JWT? Guida chiara ai JSON Web Token

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.

Cos'è un JWT? Guida chiara ai JSON Web Token

JWT in termini semplici

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>.

Perché usare un 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é:

  • funziona bene tra più servizi (API gateway, microservizi)
  • si adatta ad app mobile e single-page app (SPA) che chiamano le API direttamente
  • riduce la necessità di uno storage di sessione condiviso tra server

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.

Autenticazione vs autorizzazione (in parole semplici)

  • Autenticazione risponde: Chi sei? (Ti autentichi e dimostri la tua identità.)
  • Autorizzazione risponde: Cosa puoi fare? (Puoi leggere fatture, modificare progetti, accedere a pagine admin, ecc.)

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.

Dove si usano i JWT

Vedrai comunemente i JWT usati come access token in:

  • API web
  • SPA
  • app mobile
  • sistemi che usano OAuth 2.0 o OpenID Connect (OIDC)

Struttura di un JWT: header, payload e signature

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…

1) Header

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 usato
  • kid: un identificatore della chiave per aiutare il verificatore a scegliere la chiave corretta durante la rotazione

Nota di sicurezza: non fidarti ciecamente dell'header. Applica una allowlist degli algoritmi che effettivamente usi e non accettare alg: "none".

2) Payload

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.

3) Signature

La signature è creata firmando header + payload:

  • HS256: una secret condivisa firma e verifica
  • RS256/ES256: una chiave privata firma; una chiave pubblica verifica

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à.

Considerazioni sulla dimensione

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.

Payload e claim: cosa puoi (e non dovresti) memorizzare

Possiedi la tua implementazione
Mantieni il controllo esportando il codice sorgente quando il setup JWT è pronto.

I claim solitamente rientrano in due categorie: registered (nomi standardizzati) e custom (campi della tua app).

Claim registrati comuni

  • iss (issuer): chi ha creato il token
  • sub (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 accettato
  • iat (issued at): quando è stato emesso il token
  • nbf (not before): il token non deve essere accettato prima di questo istante

Claim custom: mantenerli minimi

Includi solo ciò di cui il servizio ricevente ha davvero bisogno per decidere l'autorizzazione.

Esempi buoni:

  • un identificatore utente interno stabile (user_id)
  • un piccolo set di ruoli/permessi (solo se riesci a mantenerli aggiornati)
  • un ID tenant/organizzazione in app multi-tenant

Evita “claim di convenienza” che duplicano molti dati di profilo. Ingrandiscono il token, diventano rapidamente obsoleti e aumentano l'impatto in caso di perdita.

Cosa non mettere mai nel payload

Poiché il payload è leggibile, non inserire:

  • password, API key, refresh token o qualsiasi valore segreto
  • dettagli di pagamento, documenti d'identità o dati personali sensibili
  • qualsiasi cosa che non vorresti venga copiata da un browser, proxy o log

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.

Come funziona la signature (e cosa garantisce)

Firmare non è criptare.

  • Firmare è come sigillare una lettera: chiunque può leggerla, ma può verificare che non sia stata modificata.
  • Crittare è come chiudere la lettera in una scatola con lucchetto: solo chi ha la chiave può leggere.

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 vs OAuth, OpenID Connect e tipi di token

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 e access/refresh 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.

  • Access token: presentato a un'API per dimostrare il permesso; può essere un JWT o un token opaco
  • Refresh token: token a vita più lunga usato per ottenere nuovi access token

Gli access token sono tipicamente a breve durata (minuti). Durate brevi limitano i danni in caso di fuga.

OpenID Connect (OIDC) e ID token

OIDC aggiunge l'autenticazione (chi è l'utente) sopra OAuth 2.0 e introduce un ID token, che di solito è un JWT.

  • ID token: per l'app client per confermare l'identità dell'utente
  • Access token: per l'API per autorizzare le richieste

Regola chiave: non usare un ID token per chiamare un'API.

Se vuoi più contesto su flussi pratici, vedi /blog/jwt-authentication-flow.

Flusso comune di autenticazione con JWT

Ottieni più crediti per costruire
Condividi ciò che hai costruito con Koder.ai o invita colleghi e guadagna crediti man mano che procedi.

Un flusso tipico è così:

1) Login

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.

2) Emissione del token

Il server firma il token e lo restituisce al client (web app, app mobile o altro servizio).

3) Chiamate API

Per endpoint protetti, il client include il JWT nell'header Authorization:

Authorization: Bearer <JWT>

4) Verifica

Prima di servire la richiesta, l'API in genere controlla:

  • signature (integrità + issuer di fiducia)
  • 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).

5) Una nota rapida sul clock skew

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.

Dove conservare i JWT in modo sicuro

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:

  • HttpOnly
  • Secure (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.

App mobile: preferisci lo storage sicuro del sistema

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.

Least privilege

Limita cosa può fare un token: usa scope/claim minimi, mantieni gli access token a breve durata e evita di incorporare dati sensibili.

Errori comuni di sicurezza da evitare

I JWT sono comodi, ma molti incidenti derivano da errori prevedibili. Tratta un JWT come denaro contante: chi lo ottiene spesso può spenderlo.

1) Scadenze troppo lunghe

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.

2) Saltare i controlli su issuer e audience

Una firma valida non basta. Verifica iss e aud, e valida claim temporali come exp e nbf.

3) Fidarsi dei payload decodificati

Decodificare non è verificare. Verifica sempre la signature sul server e applica l'autorizzazione lato server.

4) Confusione sugli algoritmi e sulle chiavi

  • Non accettare qualsiasi algoritmo dichiarato dal token. Usa una allowlist.
  • Non confondere chiavi simmetriche (HS256) con coppie chiave pubblica/privata (RS256/ES256).
  • Minimizza il blast radius separando le chiavi per ambiente e ruotandole regolarmente.

5) Perdite di token via URL, log e referrer

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.

6) Nessun piano di rotazione o revoca delle chiavi

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.

Quando usare JWT (e quando no)

Salta il boilerplate JWT
Lascia che Koder.ai gestisca il wiring ripetitivo mentre ti concentri sulla rotazione delle chiavi e sulle policy.

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.

Buoni casi d'uso per JWT

  • API stateless su larga scala: verifica locale (firma + expiry) senza lookup sessione per ogni richiesta
  • Più servizi / microservizi: regole di verifica condivise e chiavi pubbliche
  • SPA e app mobile: client che chiamano le API direttamente
  • Access token a breve durata: ridotto impatto in caso di furto

Quando JWT è una cattiva scelta

  • Revoca istantanea obbligatoria: le sessioni server-side sono più semplici se serve “logout ovunque ora” senza infrastrutture aggiuntive
  • Hai bisogno di trasportare dati sensibili: i JWT tipici sono firmati, non cifrati
  • Token a lunga durata: sono ad alto valore e interessano maggiormente gli attaccanti

Per app web tradizionali server-rendered dove l'invalidazione è importante, sessioni server-side con cookie HttpOnly sono spesso il default più semplice e sicuro.

Checklist rapida per decidere

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.

Checklist pratica e FAQ

Checklist di verifica (cosa controllare ogni volta)

  1. La signature è valida

Verifica con la chiave corretta e l'algoritmo atteso. Rifiuta firme invalide—niente eccezioni.

  1. exp (expiration)

Assicurati che il token non sia scaduto.

  1. nbf (not before)

Se presente, assicurati che il token non venga usato troppo presto.

  1. aud (audience)

Conferma che il token fosse destinato alla tua API/servizio.

  1. iss (issuer)

Conferma che il token provenga dall'issuer atteso.

  1. Controlli di sanità (consigliati)

Valida il formato del token, imponi una dimensione massima e rifiuta tipi di claim inaspettati per ridurre bug ai margini.

Scegliere HS256 vs RS256/ES256

  • HS256 (chiave simmetrica): un secret condiviso firma e verifica.

    • Buono per: una singola app/API controllata da un unico team.
    • Attenzione: chiunque verifichi con il secret può anche mintare token.
  • RS256 / ES256 (chiavi asimmetriche): la chiave privata firma; la chiave pubblica verifica.

    • Buono per: più servizi che verificano token; distribuire chiavi pubbliche senza abilitare la firma.
    • Nota operativa: la rotazione è spesso più sicura perché solo il signer detiene la chiave privata.

Regola pratica: se più sistemi indipendenti devono verificare i token (o non ti fidi pienamente di ogni verificatore), preferisci RS256/ES256.

Monitoraggio e logging (senza esporre token)

  • Non loggare token grezzi (header, cookie, query string).
  • Se ti serve correlazione, registra un fingerprint del token (es. un hash) o metadati sicuri (iss, aud, e un user ID solo se la policy lo consente).
  • Osserva anomalie: fallimenti di firma, picchi di token scaduti, audience/issuer insoliti e pattern sospetti di refresh.

FAQ

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.

Costruire app protette da JWT più velocemente con Koder.ai

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).

Domande frequenti

What is a JWT, and where do I usually send it?

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.

How is JWT authentication different from server sessions?

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.

What are the three parts of a JWT (header, payload, signature)?

Un JWT è composto da tre parti codificate in Base64URL separate da punti:

  • header.payload.signature

L'header descrive come è stato firmato, il payload contiene i claim (come sub, exp, aud) e la signature permette al server di rilevare manomissioni.

Is a JWT encrypted, and can people read what’s inside?

No. I JWT standard sono di solito firmati, non criptati.

  • La firma dimostra integrità (non è stato modificato) e autenticità (emesso da un signer di fiducia).
  • Chiunque ottenga il token può decodificare Base64URL e leggere header e payload.

Se serve riservatezza, considera JWE (token criptati) o conserva i dati sensibili lato server e metti solo un identificatore nel JWT.

What does the JWT signature guarantee—and what doesn’t it guarantee?

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:

  • la riservatezza del contenuto del payload
  • che l'utente sia ancora attivo (a meno che il server non lo verifichi)
  • la revoca automatica prima di exp

Tratta il token come una credenziale: se viene compromesso, spesso può essere riutilizzato fino alla scadenza.

What are `alg` and `kid` in the JWT header, and why do they matter?

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:

  • Usa una allowlist degli algoritmi attesi; non accettare valori alg arbitrari.
  • Non accettare alg: "none".
  • Non lasciare che un kid non attendibile causi comportamenti di lookup della chiave non sicuri.
Which JWT claims should I include in the payload?

Inizia con i claim registrati standard e mantieni i custom al minimo.

Claim comuni registrati:

  • 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.

How do JWT, OAuth 2.0, and OpenID Connect relate (access tokens vs ID tokens)?

JWT è un formato di token; OAuth 2.0 e OpenID Connect sono protocolli.

Mappatura tipica:

  • Access token: usato per chiamare un'API (può essere un JWT o un token opaco).
  • ID token (OIDC): usato dall'app client per confermare l'identità (di solito un JWT).
  • Refresh token: usato per ottenere nuovi access token (spesso opaco; trattalo come altamente sensibile).

Importante: non usare un ID token per chiamare un'API solo perché “somiglia” a un access token JWT.

Where should I store JWTs safely in a browser app?

Per le app browser, le opzioni comuni sono:

  • In memoria: riduce il rischio di furto “a posteriori”, ma resta vulnerabile durante un XSS attivo. Abbinalo a token a breve vita e a un flusso di refresh.
  • localStorage/sessionStorage: 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.
  • Cookie HttpOnly Secure: spesso il default più sicuro per il web perché JS non può leggerli; richiedono però protezioni CSRF (es. SameSite + 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.

What checks should my API perform when validating a JWT?

Al minimo, valida:

  • firma (con la chiave corretta e l'algoritmo allowlistato)
  • exp (non scaduto)
  • iss (issuer atteso)
  • aud (destinato alla tua API)
  • nbf (se presente)

Aggiungi anche protezioni pratiche:

  • imposta una dimensione massima del token
  • rifiuta tipi di claim inaspettati
  • consenti un piccolo clock skew per evitare problemi di drift temporale

Related posts