Ogni volta che un utente accede a un'applicazione SaaS, viene generato un
token di autenticazione
e consegnato al browser o all'app mobile. Quel token porta al suo interno un orologio silenzioso. Il campo di
scadenza JWT, memorizzato come un semplice Unix timestamp, comunica a ogni server che lo legge esattamente quando smettere di fidarsi della credenziale. Sbagliare quel timestamp anche solo di pochi secondi può bloccare gli utenti troppo presto o, peggio, lasciare attiva una sessione valida molto più a lungo di quanto la tua policy di sicurezza consenta. Capire come funzionano i claim di un
JSON web token, in particolare
exp
e
iat
, è una delle cose più utili che un team SaaS possa fare per rafforzare l'autenticazione senza aggiungere attrito.
Punti chiave:
-
I claim
expeiatin un JWT JSON web token sono sempre Unix timestamp espressi in secondi interi, non in millisecondi. - Lo scarto di clock tra server può invalidare silenziosamente i token o prolungare le sessioni oltre la policy - una finestra di tolleranza di 60 secondi è la soluzione standard del settore.
- Impostare la scadenza del token troppo lunga aumenta il rischio in caso di violazione; troppo corta compromette l'esperienza utente. Una formula concreta ti aiuta a scegliere il valore giusto.
- Puoi decodificare e verificare qualsiasi timestamp di un JSON web token in secondi usando un convertitore di epoch Unix, senza bisogno di librerie.
Indice dei contenuti
- Cos'è un JWT e perché i timestamp vivono al suo interno
-
I claim
expeiatspiegati - Un esempio concreto: decodificare i timestamp reali di un token
- Clock skew: il killer silenzioso dei token
- Scegliere la scadenza giusta per il tuo prodotto SaaS
- Passi pratici per implementare una scadenza JWT sicura
- Conclusione
Cos'è un JWT e perché i timestamp vivono al suo interno
Un JSON web token è una credenziale compatta e sicura per gli URL, composta da tre parti codificate in Base64 separate da punti: un header, un payload e una firma. Il payload è dove risiedono i dati sensibili al tempo. Poiché i JWT sono stateless, il server non consulta un database per validarli. Legge invece i claim incorporati nel payload e si fida della firma crittografica. Questo approccio è veloce e scalabile, ma crea un vincolo reale: una volta emesso un token, il server non può "eliminarlo". L'unico modo affidabile per limitarne la durata è incorporare direttamente nel token stesso un timestamp di scadenza.
Ecco perché il tempo, in particolare il tempo Unix epoch, è centrale per la sicurezza dei JWT. La specifica RFC 7519 che definisce i JWT impone che i claim temporali siano espressi come valori "NumericDate", ovvero semplicemente il numero di secondi trascorsi dal 1° gennaio 1970 UTC. Nessun fuso orario. Nessuna formattazione locale. Solo un intero che qualsiasi server nel mondo può confrontare con il proprio orologio.
I claim
exp
e
iat
spiegati
La specifica JWT definisce diversi claim registrati. Due sono i più importanti per la gestione del ciclo di vita del token:
-
exp(Expiration Time): Il timestamp dopo il quale il token non deve essere accettato. I server sono tenuti a rifiutare qualsiasi token in cui il tempo corrente sia uguale o superiore a questo valore. È il meccanismo centrale della scadenza JWT. -
iat(Issued At): Il timestamp in cui il token è stato creato. Il claim iat non viene verificato di default, ma è estremamente utile. Permette di calcolare l'età di un token, applicare una policy di durata massima indipendentemente daexp, e rilevare token emessi in modo sospettosamente lontano nel passato.
Un terzo claim,
nbf
(Not Before), definisce il momento più antico in cui un token è valido. Viene usato meno frequentemente, ma segue lo stesso formato Unix timestamp.
Tutti e tre i valori sono interi. Se il tuo sistema li genera in millisecondi (un errore comune quando si usa
Date.now()
in JavaScript), il numero risultante sarà circa 1.000 volte più grande del previsto. Un server che confronta
exp
con il secondo epoch corrente vedrà un token che sembra scadere nell'anno 33.658 e non lo rifiuterà mai. Si tratta di un vero bug in produzione che ha colpito diversi team SaaS.
Un esempio concreto: decodificare i timestamp reali di un token
Supponiamo che il tuo servizio di autenticazione emetta il seguente payload JWT dopo che un utente ha effettuato l'accesso alle 10:00 UTC del 1° luglio 2025:
{
"sub": "user_8821",
"iat": 1751364000,
"exp": 1751367600,
"role": "admin"
}
Vediamo cosa significano quei numeri:
| Claim | Unix Timestamp | Leggibile (UTC) | Significato |
|---|---|---|---|
iat
|
1751364000 | 2025-07-01 10:00:00 | Il token è stato emesso in questo momento |
exp
|
1751367600 | 2025-07-01 11:00:00 | Il token scade esattamente 1 ora dopo |
La differenza è esattamente 3.600 secondi, ovvero un'ora. Qualsiasi server che riceve questo token dopo le 11:00:00 UTC deve rifiutarlo. Per verificarlo manualmente, sottrai
iat
da
exp
: 1751367600 - 1751364000 = 3600 secondi. Puoi confermare il corrispondente valore leggibile di questi numeri in un istante usando un convertitore di Unix timestamp, che è esattamente il tipo di controllo rapido che previene il bug millisecondi-vs-secondi menzionato in precedenza.
Per un approfondimento su come i database dovrebbero memorizzare questi valori, consulta la nostra guida sui
Unix timestamp nei database, poiché lo stesso formato intero si applica sia che tu stia salvando
exp
in un token o in una tabella di audit log.
Clock skew: il killer silenzioso dei token
Ecco un problema reale che coglie i team di sorpresa. In un sistema distribuito, il server di autenticazione e il server API sono due macchine diverse. I loro orologi di sistema sono sincronizzati via NTP, ma non sono mai perfettamente allineati. Una differenza da 30 a 90 secondi è comune negli ambienti cloud.
Considera questo scenario: un token con
exp = 1751367600
viene validato da un server API il cui orologio segna 1751367610, appena 10 secondi dopo la scadenza. Il token viene rifiutato. L'utente riceve un errore 401. Dal suo punto di vista, aveva appena effettuato l'accesso e l'app si è rotta.
La soluzione standard è integrare una tolleranza al clock skew nella logica di validazione. La maggior parte delle librerie JWT supporta un parametro di leeway. Un valore di 60 secondi è ampiamente accettato ed è citato nella specifica OpenID Connect Core. Impostalo, documentalo e assicurati che ogni servizio nel tuo stack utilizzi lo stesso valore.
Regola pratica:
Aggiungi un leeway di 60 secondi alla validazione di
exp
. Non aggiungere mai leeway ai controlli su
iat
, perché consentirebbe di accettare token emessi nel futuro, il che è un segnale d'allarme per gli attacchi di replay.
Scegliere la scadenza giusta per il tuo prodotto SaaS
Il valore corretto per la scadenza del token dipende dalla sensibilità della tua applicazione e dal comportamento atteso della sessione. Ecco un framework pratico:
- App ad alta sensibilità (banking, sanità, dashboard di amministrazione): da 15 a 30 minuti per gli access token. Usa i refresh token per rinnovare le sessioni in modo silenzioso.
- App SaaS standard (gestione progetti, CRM, analytics): da 1 a 8 ore. Adatta la durata alla lunghezza tipica di una sessione lavorativa.
- API a basso rischio o in sola lettura: fino a 24 ore, ma abbina la rotazione del token alle azioni sensibili.
- Token di servizio machine-to-machine: possono essere più lunghi (giorni o settimane), ma devono avere uno scope ristretto e essere ruotati periodicamente.
Una formula utile per calcolare il valore di
exp
al momento dell'emissione:
// Esempio Node.js
const iat = Math.floor(Date.now() / 1000); // tempo corrente in secondi
const ttl = 3600; // time-to-live: 1 ora in secondi
const exp = iat + ttl;
const payload = {
sub: userId,
iat: iat,
exp: exp
};
Nota la divisione esplicita per 1000 per convertire i millisecondi in secondi. Questa singola riga previene il bug più comune sui timestamp JWT nelle applicazioni JavaScript.
Passi pratici per implementare una scadenza JWT sicura
Ecco una checklist concreta che puoi applicare oggi a qualsiasi sistema di autenticazione SaaS:
-
Includi sempre sia
iatcheexp. Il claimiatè tecnicamente opzionale, ma ti fornisce una traccia di audit e consente di applicare un'età massima indipendentemente dalla scadenza. -
Verifica il formato del timestamp prima di andare in produzione.
Decodifica il tuo token e controlla che
expsia un intero a 10 cifre. Un valore a 13 cifre indica che sono entrati i millisecondi. - Imposta un leeway di clock skew di 60 secondi nel tuo middleware di validazione. Applicalo in modo coerente su ogni servizio che consuma token di autenticazione.
- Usa access token di breve durata con refresh token. Un access token da 15 minuti abbinato a un refresh token da 7 giorni è molto più sicuro di un singolo access token da 7 giorni, perché il refresh token può essere revocato lato server.
-
Registra il valore
iatper ogni richiesta autenticata. Questo ti permette di rilevare anomalie, come lo stesso token utilizzato contemporaneamente da due aree geografiche diverse. -
Testa la scadenza in staging con il tempo accelerato.
Simula un salto dell'orologio oltre il valore di
expe verifica che la tua app gestisca il 401 in modo corretto, senza crash o loop.
Se hai bisogno di convertire rapidamente un valore grezzo di
exp
da un token in una data leggibile, o di verificare quale timestamp impostare per una determinata durata, il
convertitore epoch sulla nostra homepage
gestisce entrambe le direzioni in un istante, senza scrivere codice.
Conclusione
La scadenza JWT non è un concetto complesso, ma è uno di quei casi in cui piccoli errori creano grandi falle di sicurezza. I claim
exp
e
iat
sono semplicemente interi, Unix timestamp contati in secondi dall'epoch. Quella semplicità è il loro punto di forza: ogni server, ogni linguaggio e ogni piattaforma può confrontare due numeri senza ambiguità. La vera competenza sta nell'applicarli correttamente, scegliendo una durata sensata per la
scadenza del token, gestendo il clock skew con una finestra di tolleranza e intercettando l'errore millisecondi-vs-secondi prima che vada in produzione. Integra queste buone pratiche nella tua pipeline di autenticazione e la tua implementazione
JSON web token
sarà al tempo stesso sicura e manutenibile.
Verifica i timestamp JWT all'istante - senza scrivere codice
Incolla qualsiasi Unix timestamp da un payload JWT e convertilo in una data leggibile con un clic. Individua gli errori millisecondi-vs-secondi prima che raggiungano la produzione.
Prova il nostro strumento gratuito →
exp
(Expiration Time) è il Unix timestamp dopo il quale il token non è più valido e deve essere rifiutato.
iat
(Issued At) è il timestamp in cui il token è stato creato. Entrambi sono interi espressi in secondi. Il claim
iat
è opzionale ma utile per l'auditing e per applicare policy di durata massima del token.
I Unix timestamp sono interi indipendenti dal fuso orario, il che li rende non ambigui su tutti i server e in tutte le aree geografiche. Stringhe di data formattate come "2025-07-01T10:00:00" possono essere interpretate in modo errato in base alle impostazioni di locale o fuso orario. Un confronto tra interi è anche più veloce e meno soggetto a errori rispetto al parsing di stringhe in sistemi di autenticazione ad alto traffico.
Un token con lunga durata rimane valido anche se l'account dell'utente viene compromesso o i suoi permessi cambiano. Poiché i JWT sono stateless, il server non può revocarli durante la loro vita. Se un attaccante ruba un token con scadenza a 30 giorni, ha 30 giorni di accesso. Finestre di scadenza brevi abbinate ai refresh token riducono significativamente questa finestra di rischio.
In JavaScript, usa sempre
Math.floor(Date.now() / 1000)
quando generi i valori
iat
o
exp
. Il metodo
Date.now()
restituisce millisecondi. Dividendo per 1000 si ottiene l'intero in secondi richiesto dalla specifica JWT. Verifica che il tuo timestamp sia un numero a 10 cifre, non a 13.
Il clock skew è la piccola differenza di tempo tra gli orologi di sistema di due server in un sistema distribuito. Anche una differenza di 30 secondi può causare il rifiuto di un token valido se l'orologio del server di validazione è leggermente avanti. La soluzione standard è configurare un leeway di 60 secondi nella tua libreria di validazione JWT per assorbire la normale deriva NTP.