Decodarea unui JSON Web Token (JWT)
- Panou de control
- Documentație
- API
Ce este un JWT (JSON Web Token)?
Un JSON Web Token, prescurtat în JWT (pronunțat "jot"), este un format compact definit de RFC 7519 permițând transportarea unei serii de revendicări (claims) între două părți. JWT-ul, sau token-ul JWT, este astăzi formatul dominant pentru a vehicula o identitate autentificată într-un API HTTP. Un JWT se prezintă ca un șir ASCII compus din trei segmente separate de puncte:
header.payload.signature
Fiecare segment este codat în Base64URL, o variantă a Base64 fără padding
= și care înlocuiește + cu - și / cu _
pentru a putea circula într-un URL sau un header HTTP fără escape suplimentar.
Important: un JWT NU este criptat. Formatul JWT standard (JWS) este simplu semnat: semnătura garantează integritatea conținutului, dar nu aduce nicio confidențialitate. Oricine poate decoda payload-ul unui JWT cu un simplu Base64URL invers, așa cum face acest instrument jwt decode online.
Anatomia unui JWT
Un json web token este compus din trei părți bine distincte, fiecare jucând un rol precis în mecanismul de autentificare:
1. Header
Header-ul este un obiect JSON care descrie cum este semnat token-ul. Conține cel puțin:
alg(algorithm): algoritmul de semnătură utilizat. Valori tipice:HS256,RS256,ES256,EdDSA.typ(type): tipul token-ului, aproape întotdeauna"JWT".kid(key ID): facultativ, identifică ce cheie trebuie să fie utilizată pentru a verifica semnătura. Practic în prezența unui parc de chei în rotație (JWKS).
2. Payload
Payload-ul conține claim-urile, adică revendicările pe care emitentul le face despre utilizator sau sesiune. RFC 7519 definește șapte claim-uri standard (registered claims):
iss(issuer): cine a emis token-ul, de exemplu"https://accounts.google.com".sub(subject): cui aparține token-ul, în practică identificatorul utilizatorului.aud(audience): cui îi este destinat token-ul. Evită ca un token emis pentru API-ul A să fie acceptat de API-ul B.exp(expiration time): timestamp Unix după care token-ul nu mai este valid.nbf(not before): timestamp înainte de care token-ul nu este încă activ.iat(issued at): timestamp de emitere a token-ului.jti(JWT ID): identificator unic al token-ului, utilizat pentru revocare și prevenirea reluării.
La aceste claim-uri standard se adaugă în general claim-uri custom proprii
aplicației (roles, scope, tenant_id, email,
permissions...).
3. Semnătura
Semnătura este un condensat criptografic calculat pe
base64url(header) + "." + base64url(payload) cu ajutorul unei chei. Ea este cea care dovedește
că nimeni nu a modificat header-ul nici payload-ul de la emitere. Algoritmii cei mai curenți:
- HS256 / HS384 / HS512: semnătură simetrică HMAC-SHA. O cheie secretă partajată între emitent și verificator. Simplu, dar nepotrivit imediat ce există mai mult de un consumator.
- RS256 / RS384 / RS512: semnătură asimetrică RSA. Emitentul semnează cu cheia sa privată, orice consumator verifică cu cheia publică corespunzătoare. Standard de facto pentru OAuth2 și OpenID Connect.
- ES256 / ES384 / ES512: semnătură asimetrică ECDSA. Aceleași proprietăți ca RS256 dar cu chei și semnături mult mai scurte.
- EdDSA (Ed25519): semnătură asimetrică modernă, rapidă și compactă.
Încă o dată: semnătura protejează integritatea, nu confidențialitatea. Payload-ul rămâne lizibil de oricine deține token-ul.
De ce să decodezi un JWT?
Operația jwt token decode răspunde mai multor nevoi concrete pentru un dezvoltator sau inginer de securitate:
- Debug de autentificare: API-ul tău returnează un 401 sau un 403, vrei să vezi
ce se află realmente în payload (
sub,scope,roles,exp) în loc să ghicești. - Verifică claim-urile: a confirma că un token conține într-adevăr revendicarea
așteptată (de exemplu
tenant_idsaupermissions) înainte de a căuta în altă parte în lanțul de autorizare. - Citește expirarea: a converti timestamp-ul
expîntr-o dată umană pentru a confirma că un token este într-adevăr expirat, sau dimpotrivă că ar trebui să fie încă valid. - Audit de securitate: a te asigura că un serviciu terț nu scurge informații sensibile în payload (e-mail-uri, identificatori interni, date personale).
- Formare și înțelegere: a vedea concret cum arată un jsonwebtoken ieșind dintr-un furnizor OAuth (Google, Auth0, Keycloak, AWS Cognito) pentru a înțelege mecanismul fără a te scufunda în doc.
- Explorare a token-urilor publice: a inspecta un JWT găsit în log-uri, într-un cookie sau într-un schimb OAuth interceptabil.
Decoder vs Verifier: distincția critică
Cele două operații par vecine dar nu au nimic de a face în termeni de garanții de securitate:
- A decoda un JWT constă în a decupa șirul pe
.și a aplica un Base64URL invers primelor două segmente. Este o simplă citire, la îndemâna oricărui script de trei linii. Nicio verificare de semnătură nu este făcută. - A verifica un JWT constă în a recalcula semnătura plecând de la header, payload și o cheie, apoi a compara rezultatul cu semnătura prezentă în token. Este ceea ce garantează că token-ul nu a fost falsificat.
Concluzie practică: a decoda nu valorează cât a avea încredere. Atâta timp cât semnătura nu a fost verificată cu cheia bună, conținutul payload-ului poate fi total inventat. Pentru faza de încredere, utilizează JWT Verifier-ul nostru.
Cum să-l utilizezi
- Recuperează JWT-ul de inspectat, de exemplu dintr-un header
Authorization: Bearer <jwt>, dintr-un cookie de sesiune, dinlocalStorage-ul browserului, sau dintr-un log aplicativ. - Lipește șirul complet în câmpul de intrare. Cele trei segmente trebuie să rămână separate de puncte.
- Instrumentul afișează imediat header-ul decodat în JSON formatat, cu algoritmul și tipul.
- Payload-ul este apoi decodat și afișat. Acolo vezi toate claim-urile standard și custom.
- Instrumentul indică de asemenea informația de semnătură (algoritm declarat, lungime), fără a o verifica.
- Pentru a confirma că token-ul nu a fost falsificat, basculează spre JWT Verifier-ul nostru cu cheia publică sau secretul așteptat.
Toată decodarea este efectuată în browserul tău în JavaScript: token-ul tău nu este niciodată trimis la serverele noastre.
JWT și securitate: capcanele de evitat
Nu stoca NICIODATĂ date sensibile în payload-ul unui JWT semnat.
Parole, numere de carduri bancare, date medicale, secrete API, identificatori interni critici: tot ceea ce se află în payload este lizibil de oricine deține token-ul, inclusiv utilizatorul însuși prin instrumentele de dezvoltare ale browserului său. Semnătura nu maschează nimic, doar dovedește că emitentul este într-adevăr cel care pretinde că este.
Câteva reguli de aur pentru a utiliza bine JWT-urile în producție:
- Verifică întotdeauna semnătura pe partea serverului înainte de a acorda cel mai mic drept. JWT Verifier-ul nostru ilustrează exact această operație.
- Preferă RS256 sau ES256 față de HS256 pentru API-uri publice. Semnătura asimetrică evită partajarea unui secret între emitent și fiecare consumator.
- Respectă întotdeauna claim-ul
exp. Un JWT fără expirare sau cu o expirare prea îndepărtată este o bombă cu ceas în caz de scurgere. - Validează
issșiaudpe partea serverului, pentru a evita ca un token legitim emis pentru alt serviciu să fie acceptat din greșeală. - Refuză
alg: "none"pe partea verificării. Este o vulnerabilitate clasică care permite unui atacator să forjeze orice payload. - Păstrează duratele de viață scurte (15 minute de exemplu) și cuplează cu un refresh token mai lung dar revocabil pe partea serverului.
Exemplu de jeton JWT decodat
Iată un JWT tipic:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJuYW1lIjoiSm9obiIsImlhdCI6MTUxNjIzOTAyMn0.jrU9j8LZcRK2_BZjqXjU7lEpJbkqmXfTQIu9vT45j-I
Odată decodat, iată conținutul său:
// Header
{
"alg": "HS256",
"typ": "JWT"
}
// Payload
{
"sub": "123",
"name": "John",
"iat": 1516239022
}
// Semnătură (binară, codată în Base64URL)
HMACSHA256(
base64url(header) + "." + base64url(payload),
secret
)
Unde să găsești un JWT de copiat?
În practică, un JWT de decriptat (în sensul de decodat) provine cel mai adesea dintr-unul din aceste locuri:
- Cookie HTTP: deschide instrumentele de dezvoltare (F12), tab-ul
Application sau Storage, apoi Cookies. Identifică un cookie numit
access_token,jwt,sessionsau similar. localStorage/sessionStorage: același panou, secțiunea Local Storage. Multe SPA-uri stochează token-ul lor acolo sub o cheietokensauauth.- Header
Authorization: tab-ul Network, selectează o cerere API, citește header-ulAuthorization: Bearer <jwt>. Copiază doar partea de dupăBearer. - Log-uri server: un JWT apare uneori în log-urile unui gateway sau ale unui reverse proxy (de evitat în producție, dar util în debug).
Întrebări frecvente
JWT-ul este criptat sau în clar?
Un JWT semnat (format JWS) este doar codat în Base64URL, nu criptat. Orice persoană care interceptează un token poate citi payload-ul în câteva secunde. Dacă trebuie să transporți date cu adevărat confidențiale în token, trebuie să utilizezi formatul JWE (JSON Web Encryption), care adaugă un strat de criptare peste semnătură. În practică, JWE-ul rămâne rar: preferăm să nu punem date sensibile într-un token și să păstrăm informațiile critice în bază pe partea serverului.
Cum să revoc un JWT înainte de expirarea sa?
Este unul dintre punctele slabe ale JWT-ului: prin construcție, serverul nu are nevoie să stocheze
starea token-ului, deci nu știe nici cum să-l marcheze ca revocat. Trei abordări
există. Listă de revocare: a menține pe partea serverului lista
jti-urilor invalidate, și a o consulta la fiecare cerere. Durate de viață scurte:
a emite access token-uri valide 5 până la 15 minute, și a utiliza un refresh token revocabil pe partea
serverului pentru a genera unele noi. Rotație a cheii de semnătură: a invalida
o întreagă generație de token-uri schimbând cheia. A doua abordare este de departe cea mai
răspândită.
Care este diferența între un JWT și o sesiune clasică?
O sesiune clasică stochează un identificator opac pe partea clientului (în general într-un cookie) și păstrează toate datele asociate (utilizator, drepturi, expirare) în memorie sau în bază pe partea serverului. Un JWT, dimpotrivă, transportă direct aceste date în token-ul semnat. Avantajul JWT: serverul nu are nevoie să stocheze sesiune, ceea ce simplifică scaling-ul orizontal și arhitectura microservicii. Inconveniente: revocarea este mai complexă, token-ul este mai voluminos la fiecare cerere, iar cea mai mică scurgere expune payload-ul.
Diferența între JWT, JWS și JWE?
JWT (RFC 7519) este un format de token generic. Poate fi implementat în două moduri concrete: JWS (RFC 7515, JSON Web Signature) care se mulțumește să semneze payload-ul, și JWE (RFC 7516, JSON Web Encryption) care îl criptează. În practică, când se vorbește de "JWT" fără precizare, se vorbește aproape întotdeauna de un JWS: un token semnat dar lizibil de toți. JWE-ul este utilizat în contexte unde confidențialitatea payload-ului este indispensabilă, de exemplu în anumite scenarii OpenID Connect avansate.
JWT-ul meu nu este acceptat de API, de ce?
Cauzele clasice sunt, în ordinea frecvenței: token expirat (verifică
claim-ul exp), semnătură invalidă (cheia secretă sau cheia publică
nu corespund celei utilizate de emitent), aud greșit
(token-ul a fost emis pentru alt serviciu), iss greșit
(emitentul declarat nu este cel așteptat), algoritm refuzat (API-ul cere
de exemplu RS256 și primește un HS256), ceasuri desincronizate între
emitent și verificator (joacă pe exp și nbf). Decodarea
token-ului cu acest instrument permite deja eliminarea jumătății din ipoteze citind direct
claim-urile.
Cum să generez un JWT?
Majoritatea limbajelor dispun de o bibliotecă dedicată: jsonwebtoken în
Node.js, PyJWT în Python, lcobucci/jwt sau
firebase/php-jwt în PHP, jjwt în Java, golang-jwt/jwt
în Go. Toate iau ca intrare un obiect payload, o cheie și un algoritm, și returnează
șirul header.payload.signature gata de trimis. Este puternic descurajată
implementarea generării manuală: criptografia comportă prea multe capcane (comparații
neconstante, gestionare incorectă a alg: none, etc.).
Decoder-ul acceptă un JWT expirat?
Da. Decoder-ul se mulțumește să afișeze conținutul token-ului fără a emite o judecată despre
validitatea sa temporală. Nu evaluează nici exp, nici nbf, nici semnătura.
Este util pentru a înțelege de ce un token a fost respins de un API: se poate
compara valoarea exp-ului cu ora actuală pentru a confirma că este într-adevăr
expirat.
JWT-ul meu este valid dacă decoder-ul îl afișează corect?
Nu. Afișarea dovedește doar că șirul este bine format (trei segmente separate de puncte, codare Base64URL corectă, JSON valid în header și în payload). Asta nu spune nimic despre autenticitatea token-ului. Un JWT integral falsificat poate fi afișat fără eroare într-un decoder, exact pentru aceasta trebuie trecut printr-un verifier.
Exemplu de cerere
curl -X POST https://cdrn.fr/api/v1/tools/jwt-decoder/execute \
-H "Content-Type: application/json" \
-d '{"token":"..."}'
Schema de intrare
| Câmp | Tip | Obligatoriu | Implicit |
|---|---|---|---|
token |
text | ✓ | – |
Puncte de acces
GET https://cdrn.fr/api/v1/tools- listează toate instrumentele disponibileGET https://cdrn.fr/api/v1/tools/jwt-decoder- obține schema acestui instrumentPOST https://cdrn.fr/api/v1/tools/jwt-decoder/execute- execută acest instrument cu un payload JSON