Greșeli exp/iat/nbf JWT: erori de revendicare în timp care încalcă autentificarea
[Securitatea dezvoltatorului27 martie 2026·8 minute de citire] [
Revendicările de timp JWT — exp, [ și nbf — sunt înșelător de simple. Sunt doar marcaje temporale Unix. Cu toate acestea, provoacă unele dintre cele mai frustrante erori de autentificare din producție: token-uri care expiră prea devreme, token-uri care funcționează pe un server, dar nu pe altul și token-uri care nu expiră deloc.
Acest articol acoperă cele mai frecvente erori de revendicare a timpului, de ce apar și cum să le remediați cu valori implicite sigure.
[ funcționează exp, iat și nbfFiecare JWT poate include trei revendicări legate de timp în sarcina sa utilă:
[Toate trei sunt date numerice: numărul de secunde de la 1970-01-01T00:00:00Z (epoca Unix). Nu milisecunde - secunde. Numai această distincție cauzează aproximativ 20% din toate erorile de timp JWT.
Utilizați Decodorul nostru JWT pentru a inspecta instantaneu revendicările de timp în orice simbol.
Eroarea #1: Folosirea milisecundelor în loc de secunde
JavaScript Date.now() returnează milisecunde. Specificația JWT necesită secunde. Setarea [ la Date.now() + 3600000 creează un token care expiră în anul 2089, nu într-o oră.
// GREȘIT — milisecunde
const exp = Date.now() + 3600000; // CORECT — secunde
const exp = Math.floor(Date.now() / 1000) + 3600;
Majoritatea bibliotecilor JWT se ocupă de acest lucru intern, dar dacă construiți încărcături utile manual, acesta este primul lucru de verificat.
Eroarea nr. 2: Lipsește o revendicare completă a exp.[
Dacă uitați să setați exp, multe biblioteci vor crea cu plăcere un simbol care nu expiră niciodată. Acesta este un risc de securitate: un token scurs rămâne valabil pentru totdeauna.
exp în mod implicit, configurați-o să facă acest lucru.
// Node.js jsonwebtoken — impune expirarea
jwt.verify(token, secret, [ Bug #3: Clock Skew Between Servers
[ A emite un token la 14:00:00. Ceasul serverului B arată 13:59:55 (cu 5 secunde în urmă). Dacă jetonul arenbf: 1711540800 (14:00:00), Serverul B îl respinge ca „nu este încă valid.”
[ lucru este obișnuit în special în:
[
[ de microservicii cu ceasuri nesincronizate
Permiteți o toleranță mică de ceas (numită și „leeway”) — de obicei 30–60 de secunde:
[// jsonwebtoken
jwt.verify(token, secret, [ // jose (Node.js)
așteaptă jwtVerify(indicativ, cheie, [
[ setați niciodată toleranța peste 2 minute. Dacă aveți nevoie de mai multe, remediați sincronizarea NTP. Eroarea #4: Comanda de validare greșită
[ corectă de validare contează. Dacă verificați semnătura după verificarea expirării, un atacator poate crea un jeton cu un viitorexp care trece de verificarea timpului, dar are o semnătură nevalidă.
[ de validare sigură:
[
[ antetul (algoritm de verificare)
[ semnătura
[ exp (respingeți dacă a expirat)
nbf (respingeți dacă nu este încă valid)iat (respingeți dacă este nerezonabil de vechi)Majoritatea bibliotecilor bine întreținute gestionează acest lucru corect, dar middleware-ul personalizat greșește adesea.
[ #5: Confuzia fusului orar în iat [ de timp JWT sunt întotdeauna UTC. Dar dezvoltatorii le creează uneori folosind ora locală:// GREȘIT — fus orar local
const iat = new Date('2026-03-27T14:00:00').getTime() / 1000; // CORECT — UTC explicit
const iat = new Date('2026-03-27T14:00:00Z').getTime() / 1000;
Fără sufixul Z, JavaScript interpretează șirul în fusul orar local, care poate schimba marcajul de timp în funcție de ore.
Revendicarea nbf este utilă pentru token-urile de activare întârziată — de exemplu, un token care ar trebui să funcționeze numai după o implementare programată. Dacă validatorul dvs. ignoră nbf, aceste jetoane pot fi folosite înainte de momentul de activare prevăzut.
Majoritatea bibliotecilor validează nbf în mod implicit, dar verifică acest lucru în configurarea ta, în special cu middleware personalizat.
Setarea exp la 30 de zile pentru un jeton de acces înfrânge scopul jetonelor de scurtă durată. Cele mai bune practici:
Pentru modele sigure de jetoane de reîmprospătare, consultați ghidul nostru despre Rotația jetoanelor de reîmprospătare JWT.
Cazuri de testare pe care ar trebui să le aibă fiecare API
Adăugați-le la suita dvs. de teste pentru a detecta erorile de revendicare a timpului mai devreme:
[exp în trecut → 401exp exact acum → 401 (limită)nbf în viitor → 401nbf puțin în viitor (în limita toleranței) → 200iat în viitor → 401 (indică modificarea)jwt.sign(sarcină utilă, secret, [
jwt.verify(token, secret, [
[ (PyJWT)
[jwt.decode(token, cheie, algoritmi=['HS256'], leeway=timedelta(secunde=30), opțiuni=[
[ (golang-jwt)
[parser := jwt.NewParser( jwt.WithLeeway(30 * time.Second), jwt.WithValidMethods([]string{"HS256"}),
)[ [
[ frecvente
[ trebui să fie obligatoriu?
În timp ce specificația JWT spune că iat este opțional, făcându-l obligatoriu ajutoare pentru depanare și urmărire de audit. Fără [, nu puteți determina când a fost creat un token, ceea ce face mai dificilă corelarea cu evenimentele de securitate.
Câtă înclinare a ceasului ar trebui să permit?
O valoare implicită de siguranță obișnuită este 30-60 de secunde. Mai mult de 2 minute introduce riscul de securitate. Dacă sistemele dvs. au nevoie de mai multe, remediați sincronizarea NTP în loc să extindeți permisiunea de deformare.
Ce cod de stare HTTP ar trebui să returnez pentru un token expirat?
Return 401 Neautorizat cu un corp de eroare clar, cum ar fi {"error": "token_expired"}. Nu returnați 403 Forbidden — ceea ce înseamnă că simbolul este valid, dar nu are permisiuni, ceea ce este o situație diferită.