# Leggi un token JWT senza inviarlo al server: claim e scadenza

> Decoder JWT online con split header/payload/signature, parsing JSON, claim explainer RFC 7519 (iss, sub, exp, iat), expiry countdown e verifica HS256.

Strumento gratuito nel browser (nessun upload): https://www.mauriziofonte.it/strumenti/jwt-decoder

Decoder per **token JWT**: split in header, payload e signature, decode base64url, parsing JSON, **claim explainer** per ogni claim standard (iss, sub, aud, exp, iat, nbf, jti) e per i custom claim degli IdP più diffusi, **expiry countdown** live, comparison side-by-side di più token, **verifica firma HS256** opzionale via WebCrypto se disponi del secret. Per analisi di sicurezza (rilevazione di alg=none, weak HS256, claim mancanti, lifetime troppo lungo) il tool dedicato è l'[audit JWT](/strumenti/audit-jwt).

## Come usare il decoder

1. **Incolla il JWT** - Tre parti separate da punto: `header.payload.signature`. Il decoder accetta JWS (signed) standard. NON accetta JWE (encrypted, 5 segmenti).
2. **Leggi le sezioni** - Header decoded: alg + typ + kid eventuale. Payload decoded: tutti i claim in formato JSON pretty-printed. Signature: stringa base64url (non decodificata, sono byte raw).
3. **Claim explainer** - Per ogni claim standard RFC 7519 (iss, sub, aud, exp, iat, nbf, jti) il decoder mostra significato e formato atteso. Per claim custom (es. roles, permissions, tenant_id) mostra il valore raw.
4. **Expiry countdown** - Se il payload ha `exp`: countdown live al momento di scadenza, con stato 'attivo' / 'scaduto da X minuti'. Utile per debug di token che vengono rifiutati lato server senza chiarezza sul perché.

## Cosa risolve, in pratica

**Lettura strutturata del payload.** Il decoder spezza il token nelle tre parti standard, decodifica base64url, parsifica il JSON e mostra il payload con sintassi pretty-printed. Per ogni claim standard di RFC 7519 (iss, sub, aud, exp, iat, nbf, jti) accanto al valore appare la spiegazione del significato e del formato atteso; per i custom claim più ricorrenti negli IdP (scope, roles, permissions, tenant_id, cognito_groups, namespaced claim Auth0) la stessa spiegazione contestuale.

**Casi d'uso operativi.** Debug di un'API che rifiuta un token, per controllare che i claim corrispondano a quanto atteso lato server. Verifica del lifetime: un `exp` in passato è la causa più frequente di 401 in test E2E e non sempre evidente alla prima lettura, il countdown live lo mostra immediatamente. Comprensione dei claim custom emessi da IdP poco familiari (Auth0, Okta, AWS Cognito, Keycloak, Azure AD), in particolare i namespaced claim del tipo `https://example.com/roles`. Confronto side-by-side fra token consecutivi di un flow OAuth (id_token, access_token, refresh_token) per evidenziarne le differenze.

**Verifica firma HS256 opzionale.** Se disponi del secret server-side per un token HS256 puoi incollarlo nel campo dedicato e verificare la firma direttamente via WebCrypto. Il calcolo HMAC-SHA256 avviene nel browser; il secret non viene trasmesso a nessun endpoint. Per token RS256/ES256, dove la verifica richiede la chiave pubblica dell'IdP e il fetch del JWKS, l'analisi corretta è quella dell'[audit JWT di sicurezza](/strumenti/audit-jwt).

## Glossario

- **JWT**: JSON Web Token, RFC 7519. Stringa header.payload.signature, base64url-encoded ognuno. Standard per API authentication moderne.
- **JWS / JWE**: JSON Web Signature (JWS, signed-only, 3 segmenti) vs JSON Web Encryption (JWE, encrypted, 5 segmenti). Questo decoder gestisce solo JWS. JWE richiede chiave per decrittare.
- **base64url**: Variante di base64 (RFC 4648 sec. 5) con caratteri url-safe: `-` al posto di `+`, `_` al posto di `/`, niente padding `=`. Usato in JWT per evitare URL-encoding aggiuntivo.
- **Claim**: Coppia chiave-valore nel payload JSON del JWT. Standard RFC 7519: iss, sub, aud, exp, iat, nbf, jti. Custom: tutto il resto (es. `roles`, `permissions`, `tenant_id`).
- **Multi-token comparison**: Confronto side-by-side di due o più JWT. Tipico per debug di flow OAuth con id_token + access_token + refresh_token.
- **Expiry countdown**: Visualizzazione live del tempo rimanente alla scadenza del token. Utile per intercettare token già scaduti (causa comune di errori 401 in produzione).

## Domande frequenti

### Decoder vs audit: quale uso?

Decoder per leggere il contenuto di un JWT (debug, ispezione, comprensione). Audit per identificare vulnerabilità di sicurezza (alg=none, weak secret, claim mancanti). Sono complementari: il decoder ti mostra cosa c'è, l'audit ti dice se ci sono problemi.

### Il decoder verifica la firma?

Per i token HS256 sì, opzionalmente, se incolli il secret server-side nel campo dedicato: la verifica HMAC-SHA256 avviene via WebCrypto direttamente nel browser. Per i token RS256, ES256 e altri algoritmi asimmetrici la verifica richiede la chiave pubblica dell'IdP e il fetch del relativo JWKS, fuori scope per un decoder commodity: usa l'SDK ufficiale del tuo IdP in modalità debug oppure passa all'[audit JWT](/strumenti/audit-jwt) per l'analisi completa di sicurezza.

### Ottengo 'token non valido': cosa controllo?

Verifica: (1) tre parti separate da punto (header.payload.signature). (2) ogni parte è base64url valida. (3) header e payload sono JSON validi. Errori comuni: token tagliato a metà nel copy-paste; spazi/newline nel mezzo (rimuoverli); JWE invece di JWS (5 segmenti, decoder JWE necessario).

### Come confronto due token side-by-side?

Decode il primo, copia il payload JSON. Decode il secondo. Apri un diff text (es. il [diff tool](/strumenti/diff-online) di questo sito) e incolla i due payload. Differenze evidenti: tipicamente `exp`, `iat`, scope/permissions distinti per access vs id token.

### Posso decodificare un token Auth0/Okta/AWS Cognito?

Sì. Tutti i provider OAuth/OIDC moderni (Auth0, Okta, AWS Cognito, Azure AD, Keycloak, Google Identity, Facebook Login) emettono JWT standard JWS. Il decoder funziona con qualunque issuer.

### Il payload ha namespaced claim tipo 'https://example.com/roles': cosa sono?

Convenzione Auth0/IdP per claim custom non in conflitto con RFC. Auth0 raccomanda namespace HTTPS-style per evitare collisioni con futuri claim standard. Il valore sotto è specifico dell'app: roles, permissions, tenant_id, ecc. Il decoder lo mostra raw, tu interpreti il significato in base al contesto.

### Expiry countdown segna 'scaduto' ma il backend lo accetta: bug?

Possibili cause: (1) clock skew lato server (server con orologio sfasato accetta token 'scaduti' di poco); (2) tolerance configurata (es. AWS Cognito accetta token scaduti fino a 10s); (3) il backend usa `iat` e una sliding window invece di `exp` rigida. Verifica con il backend: la regola 'exp < now -> 401' non è universale.

### Posso fare paste di un JWT con BOM o whitespace ai bordi?

Sì, il decoder fa `trim()` dell'input prima del parsing. BOM (byte order mark UTF-8) viene strippato. Spazi e newline interni a una delle 3 parti però rompono il parsing: copia/incolla con cura. Se il JWT viene da un terminal output, fai attenzione a line wrap automatico.

---
Uno strumento di Maurizio Fonte, senior backend engineer. Tutti gli strumenti: https://www.mauriziofonte.it/strumenti/
