Decodificare un JSON Web Token (JWT)

decodifica il tuo token JWT (JSON Web Token) e mostra le informazioni che contiene in modo leggibile e strutturato

Cos'è un JWT (JSON Web Token)?

Un JSON Web Token, abbreviato in JWT (pronunciato "jot"), è un formato compatto definito dalla RFC 7519 che permette di trasportare una serie di rivendicazioni (claim) tra due parti. Il JWT, o token JWT, è oggi il formato dominante per veicolare un'identità autenticata in un'API HTTP. Un JWT si presenta come una stringa ASCII composta da tre segmenti separati da punti:

header.payload.signature

Ogni segmento è codificato in Base64URL, una variante di Base64 senza padding = e che sostituisce + con - e / con _ per poter circolare in un URL o un header HTTP senza escape aggiuntivo.

Importante: un JWT NON è cifrato. Il formato JWT standard (JWS) è semplicemente firmato: la firma garantisce l'integrità del contenuto, ma non apporta alcuna riservatezza. Chiunque può decodificare il payload di un JWT con un semplice Base64URL inverso, come fa questo strumento jwt decode online.

Anatomia di un JWT

Un json web token è composto da tre parti ben distinte, ognuna che gioca un ruolo preciso nel meccanismo di autenticazione:

1. Header

L'header è un oggetto JSON che descrive come il token è firmato. Contiene almeno:

  • alg (algorithm): l'algoritmo di firma usato. Valori tipici: HS256, RS256, ES256, EdDSA.
  • typ (type): il tipo del token, quasi sempre "JWT".
  • kid (key ID): facoltativo, identifica quale chiave deve essere usata per verificare la firma. Pratico in presenza di un parco di chiavi in rotazione (JWKS).

2. Payload

Il payload contiene i claim, ossia le rivendicazioni che l'emettitore fa sull'utente o sulla sessione. La RFC 7519 definisce sette claim standard (registered claim):

  • iss (issuer): chi ha emesso il token, per esempio "https://accounts.google.com".
  • sub (subject): a chi appartiene il token, in pratica l'identificatore utente.
  • aud (audience): a chi è destinato il token. Evita che un token emesso per l'API A sia accettato dall'API B.
  • exp (expiration time): timestamp Unix dopo il quale il token non è più valido.
  • nbf (not before): timestamp prima del quale il token non è ancora attivo.
  • iat (issued at): timestamp di emissione del token.
  • jti (JWT ID): identificatore unico del token, usato per la revoca e la prevenzione del replay.

A questi claim standard si aggiungono generalmente claim custom propri dell'applicazione (roles, scope, tenant_id, email, permissions...).

3. Signature

La firma è un digest crittografico calcolato su base64url(header) + "." + base64url(payload) con l'aiuto di una chiave. È lei che prova che nessuno ha modificato l'header né il payload dall'emissione. Gli algoritmi più comuni:

  • HS256 / HS384 / HS512: firma simmetrica HMAC-SHA. Una chiave segreta condivisa tra l'emettitore e il verificatore. Semplice, ma inadatta non appena c'è più di un consumatore.
  • RS256 / RS384 / RS512: firma asimmetrica RSA. L'emettitore firma con la sua chiave privata, qualsiasi consumatore verifica con la chiave pubblica corrispondente. Standard di fatto per OAuth2 e OpenID Connect.
  • ES256 / ES384 / ES512: firma asimmetrica ECDSA. Stesse proprietà di RS256 ma con chiavi e firme molto più corte.
  • EdDSA (Ed25519): firma asimmetrica moderna, rapida e compatta.

Ancora una volta: la firma protegge l'integrità, non la riservatezza. Il payload resta leggibile da chiunque possegga il token.

Perché decodificare un JWT?

L'operazione jwt token decode risponde a vari bisogni concreti per uno sviluppatore o un ingegnere della sicurezza:

  • Debug di autenticazione: la vostra API restituisce un 401 o un 403, volete vedere cosa si trova realmente nel payload (sub, scope, roles, exp) piuttosto che indovinare.
  • Verificare i claim: confermare che un token contenga effettivamente la rivendicazione attesa (per esempio tenant_id o permissions) prima di cercare altrove nella catena di autorizzazione.
  • Leggere la scadenza: convertire il timestamp exp in data umana per confermare che un token sia effettivamente scaduto, o al contrario che dovrebbe essere ancora valido.
  • Audit di sicurezza: assicurarsi che un servizio terzo non faccia trapelare informazioni sensibili nel payload (e-mail, identificatori interni, dati personali).
  • Formazione e comprensione: vedere concretamente come si presenta un jsonwebtoken uscente da un provider OAuth (Google, Auth0, Keycloak, AWS Cognito) per capire la meccanica senza tuffarsi nella documentazione.
  • Esplorazione di token pubblici: ispezionare un JWT trovato nei log, in un cookie o in uno scambio OAuth intercettabile.

Decoder vs Verifier: la distinzione critica

Le due operazioni sembrano vicine ma non hanno nulla a che fare in termini di garanzie di sicurezza:

  • Decodificare un JWT consiste nel tagliare la stringa sui . e applicare un Base64URL inverso ai primi due segmenti. È una semplice lettura, alla portata di qualsiasi script di tre righe. Nessuna verifica di firma viene fatta.
  • Verificare un JWT consiste nel ricalcolare la firma a partire da header, payload e una chiave, poi confrontare il risultato con la firma presente nel token. È ciò che garantisce che il token non sia stato falsificato.

Conclusione pratica: decodificare non vale fidarsi. Finché la firma non è stata verificata con la chiave giusta, il contenuto del payload può essere totalmente falso. Per la fase di fiducia, usate il nostro JWT Verifier.

Come usarlo

  1. Recuperate il JWT da ispezionare, per esempio da un header Authorization: Bearer <jwt>, da un cookie di sessione, dal localStorage del browser, o da un log applicativo.
  2. Incollate la stringa completa nel campo di input. I tre segmenti devono restare separati da punti.
  3. Lo strumento mostra immediatamente l'header decodificato in JSON formattato, con l'algoritmo e il tipo.
  4. Il payload viene poi decodificato e mostrato. Vedete tutti i claim standard e custom.
  5. Lo strumento indica anche l'informazione di firma (algoritmo dichiarato, lunghezza), senza verificarla.
  6. Per confermare che il token non sia stato falsificato, passate al nostro JWT Verifier con la chiave pubblica o il secret atteso.

Tutta la decodifica viene effettuata nel vostro browser in JavaScript: il vostro token non viene mai inviato ai nostri server.

JWT e sicurezza: le trappole da evitare

Non memorizzate MAI dati sensibili nel payload di un JWT firmato.

Password, numeri di carta di credito, dati medici, secret API, identificatori interni critici: tutto ciò che si trova nel payload è leggibile da chiunque possieda il token, incluso l'utente stesso tramite gli strumenti di sviluppo del suo browser. La firma non maschera nulla, prova solo che l'emettitore sia effettivamente chi pretende di essere.

Alcune regole d'oro per usare bene i JWT in produzione:

  • Verificare sempre la firma lato server prima di concedere il minimo diritto. Il nostro JWT Verifier illustra esattamente questa operazione.
  • Preferire RS256 o ES256 a HS256 per le API pubbliche. La firma asimmetrica evita di condividere un secret tra l'emettitore e ogni consumatore.
  • Sempre rispettare il claim exp. Un JWT senza scadenza o con una scadenza troppo lontana è una bomba a orologeria in caso di fuga.
  • Validare iss e aud lato server, per evitare che un token legittimo emesso per un altro servizio sia accettato per errore.
  • Rifiutare alg: "none" lato verifica. È una falla classica che permette a un attaccante di forgiare qualsiasi payload.
  • Tenere le durate di vita corte (15 minuti per esempio) e accoppiare a un refresh token più lungo ma revocabile lato server.

Esempio di token JWT decodificato

Ecco un JWT tipico:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJuYW1lIjoiSm9obiIsImlhdCI6MTUxNjIzOTAyMn0.jrU9j8LZcRK2_BZjqXjU7lEpJbkqmXfTQIu9vT45j-I

Una volta decodificato, ecco il suo contenuto:

// Header
{
  "alg": "HS256",
  "typ": "JWT"
}

// Payload
{
  "sub": "123",
  "name": "John",
  "iat": 1516239022
}

// Signature (binaire, encodé en Base64URL)
HMACSHA256(
  base64url(header) + "." + base64url(payload),
  secret
)

Dove trovare un JWT da copiare?

In pratica, un JWT da decifrare (nel senso di decodificare) proviene il più delle volte da una di queste posizioni:

  • Cookie HTTP: aprite gli strumenti di sviluppo (F12), scheda Application o Storage, poi Cookie. Individuate un cookie chiamato access_token, jwt, session o simili.
  • localStorage / sessionStorage: stesso pannello, sezione Local Storage. Molte SPA vi memorizzano il loro token sotto una chiave token o auth.
  • Header Authorization: scheda Network, selezionare una richiesta API, leggere l'header Authorization: Bearer <jwt>. Copiare solo la parte dopo Bearer .
  • Log server: un JWT appare a volte nei log di un gateway o di un reverse proxy (da evitare in produzione, ma utile in debug).

Domande frequenti

Il JWT è cifrato o in chiaro?

Un JWT firmato (formato JWS) è solo codificato in Base64URL, non cifrato. Chiunque intercetti un token può leggere il payload in pochi secondi. Se dovete trasportare dati realmente confidenziali nel token, bisogna usare il formato JWE (JSON Web Encryption), che aggiunge uno strato di cifratura sopra alla firma. In pratica, il JWE resta raro: si preferisce non mettere dati sensibili in un token e conservare le informazioni critiche in database lato server.

Come revocare un JWT prima della sua scadenza?

È uno dei punti deboli del JWT: per costruzione, il server non ha bisogno di memorizzare lo stato del token, quindi non sa nemmeno come marcarlo come revocato. Esistono tre approcci. Lista di revoca: mantenere lato server l'elenco dei jti invalidati, e consultarla a ogni richiesta. Durate di vita corte: emettere access token validi 5-15 minuti, e usare un refresh token revocabile lato server per generarne di nuovi. Rotazione di chiave di firma: invalidare tutta una generazione di token cambiando la chiave. Il secondo approccio è di gran lunga il più diffuso.

Qual è la differenza tra un JWT e una sessione classica?

Una sessione classica memorizza un identificatore opaco lato client (generalmente in un cookie) e conserva tutti i dati associati (utente, diritti, scadenza) in memoria o in database lato server. Un JWT, al contrario, trasporta direttamente questi dati nel token firmato. Vantaggio del JWT: il server non ha bisogno di memorizzare sessione, il che semplifica lo scaling orizzontale e l'architettura microservizi. Inconvenienti: la revoca è più complessa, il token è più voluminoso a ogni richiesta, e la minima fuga espone il payload.

Differenza tra JWT, JWS e JWE?

JWT (RFC 7519) è un formato di token generico. Può essere implementato in due modi concreti: JWS (RFC 7515, JSON Web Signature) che si limita a firmare il payload, e JWE (RFC 7516, JSON Web Encryption) che lo cifra. In pratica, quando si parla di "JWT" senza precisazione, si parla quasi sempre di un JWS: un token firmato ma leggibile da tutti. Il JWE è usato nei contesti dove la riservatezza del payload è indispensabile, per esempio in alcuni scenari OpenID Connect avanzati.

Il mio JWT non viene accettato dall'API, perché?

Le cause classiche sono, in ordine di frequenza: token scaduto (verificate il claim exp), firma invalida (chiave segreta o chiave pubblica non corrisponde a quella usata dall'emettitore), aud sbagliato (il token è stato emesso per un altro servizio), iss sbagliato (l'emettitore dichiarato non è quello atteso), algoritmo rifiutato (l'API richiede per esempio RS256 e riceve un HS256), orologi desincronizzati tra emettitore e verificatore (incide su exp e nbf). Decodificare il token con questo strumento permette già di eliminare metà delle ipotesi leggendo direttamente i claim.

Come generare un JWT?

La maggior parte dei linguaggi dispone di una libreria dedicata: jsonwebtoken in Node.js, PyJWT in Python, lcobucci/jwt o firebase/php-jwt in PHP, jjwt in Java, golang-jwt/jwt in Go. Tutte prendono in input un oggetto payload, una chiave e un algoritmo, e restituiscono la stringa header.payload.signature pronta da inviare. È fortemente sconsigliato implementare la generazione a mano: la crittografia comporta troppe trappole (confronti non costanti, gestione errata di alg: none, ecc.).

Il decoder accetta un JWT scaduto?

Sì. Il decoder si limita a mostrare il contenuto del token senza esprimere un giudizio sulla sua validità temporale. Non valuta né exp, né nbf, né la firma. È utile per capire perché un token è stato rifiutato da un'API: si può confrontare il valore di exp con l'ora attuale per confermare che sia effettivamente scaduto.

Il mio JWT è valido se il decoder lo mostra correttamente?

No. La visualizzazione prova solo che la stringa è ben formata (tre segmenti separati da punti, codifica Base64URL corretta, JSON valido nell'header e nel payload). Non dice nulla sull'autenticità del token. Un JWT interamente falsificato può visualizzarsi senza errori in un decoder, è precisamente per questo che bisogna passarlo a un verifier.

Esempio di richiesta

curl -X POST https://cdrn.fr/api/v1/tools/jwt-decoder/execute \
  -H "Content-Type: application/json" \
  -d '{"token":"..."}'

Schema di input

Campo Tipo Richiesto Predefinito
token text

Endpoint

  • GET https://cdrn.fr/api/v1/tools - elenca tutti gli strumenti disponibili
  • GET https://cdrn.fr/api/v1/tools/jwt-decoder - recupera lo schema di questo strumento
  • POST https://cdrn.fr/api/v1/tools/jwt-decoder/execute - esegue questo strumento con un payload JSON