Zdekoduj JSON Web Token (JWT)

dekoduje JSON Web Token i pokazuje jego header oraz payload w czytelnej, ustrukturyzowanej formie

Czym jest JWT (JSON Web Token)?

JSON Web Token, skrót JWT (wymawiany „jot"), to kompaktowy format zdefiniowany przez RFC 7519, pozwalający przenosić serię oświadczeń (claims) między dwiema stronami. JWT, lub jeton JWT, jest dziś dominującym formatem przenoszenia uwierzytelnionej tożsamości w API HTTP. JWT prezentuje się jako ciąg ASCII złożony z trzech segmentów oddzielonych kropkami:

header.payload.signature

Każdy segment jest zakodowany w Base64URL, wariancie Base64 bez paddingu =, który zastępuje + przez - i / przez _, aby móc krążyć w URL lub nagłówku HTTP bez dodatkowego escapowania.

Ważne: JWT NIE jest zaszyfrowany. Standardowy format JWT (JWS) jest po prostu podpisany: podpis gwarantuje integralność treści, ale nie zapewnia żadnej poufności. Każdy może odkodować payload JWT prostym odwrotnym Base64URL, jak to robi to narzędzie jwt decode online.

Anatomia JWT

json web token składa się z trzech wyraźnie odrębnych części, z których każda odgrywa precyzyjną rolę w mechanizmie uwierzytelniania:

1. Header

Nagłówek to obiekt JSON, który opisuje, jak token jest podpisany. Zawiera co najmniej:

  • alg (algorithm): używany algorytm podpisu. Typowe wartości: HS256, RS256, ES256, EdDSA.
  • typ (type): typ tokenu, prawie zawsze "JWT".
  • kid (key ID): opcjonalne, identyfikuje, który klucz powinien być użyty do weryfikacji podpisu. Praktyczne w obecności puli kluczy w rotacji (JWKS).

2. Payload

Payload zawiera claims, czyli oświadczenia, które emitent czyni na temat użytkownika lub sesji. RFC 7519 definiuje siedem standardowych claims (registered claims):

  • iss (issuer): kto wyemitował token, na przykład "https://accounts.google.com".
  • sub (subject): do kogo należy token, w praktyce identyfikator użytkownika.
  • aud (audience): do kogo przeznaczony jest token. Zapobiega temu, że token wyemitowany dla API A jest akceptowany przez API B.
  • exp (expiration time): timestamp Unix, po którym token jest nieważny.
  • nbf (not before): timestamp, przed którym token nie jest jeszcze aktywny.
  • iat (issued at): timestamp emisji tokenu.
  • jti (JWT ID): unikalny identyfikator tokenu, używany do unieważniania i zapobiegania powtórnemu użyciu.

Do tych standardowych claims dodaje się zwykle custom claims specyficzne dla aplikacji (roles, scope, tenant_id, email, permissions...).

3. Signature

Podpis to kryptograficzny skrót obliczony na base64url(header) + "." + base64url(payload) przy pomocy klucza. To on udowadnia, że nikt nie zmodyfikował nagłówka ani payloadu od emisji. Najczęstsze algorytmy:

  • HS256 / HS384 / HS512: symetryczny podpis HMAC-SHA. Wspólny sekretny klucz dzielony między emitentem a weryfikatorem. Proste, ale nieodpowiednie, gdy jest więcej niż jeden konsument.
  • RS256 / RS384 / RS512: asymetryczny podpis RSA. Emitent podpisuje swoim kluczem prywatnym, każdy konsument weryfikuje odpowiadającym kluczem publicznym. Standard de facto dla OAuth2 i OpenID Connect.
  • ES256 / ES384 / ES512: asymetryczny podpis ECDSA. Te same właściwości co RS256, ale ze znacznie krótszymi kluczami i podpisami.
  • EdDSA (Ed25519): nowoczesny, szybki i kompaktowy podpis asymetryczny.

Ponownie: podpis chroni integralność, a nie poufność. Payload pozostaje czytelny dla każdego, kto posiada token.

Dlaczego dekodować JWT?

Operacja jwt token decode odpowiada na kilka konkretnych potrzeb programisty lub inżyniera bezpieczeństwa:

  • Debugowanie uwierzytelnienia: twoje API zwraca 401 lub 403, chcesz zobaczyć, co naprawdę jest w payloadzie (sub, scope, roles, exp) zamiast zgadywać.
  • Weryfikacja claims: potwierdzenie, że token zawiera oczekiwane oświadczenie (na przykład tenant_id lub permissions) przed szukaniem gdzie indziej w łańcuchu autoryzacji.
  • Odczytanie wygaśnięcia: konwersja timestampa exp na ludzką datę, aby potwierdzić, że token jest dobrze wygasły lub przeciwnie, że powinien być jeszcze ważny.
  • Audyt bezpieczeństwa: upewnienie się, że usługa zewnętrzna nie ujawnia wrażliwych informacji w payloadzie (e-maile, wewnętrzne identyfikatory, dane osobowe).
  • Szkolenie i zrozumienie: konkretne zobaczenie, jak wygląda jsonwebtoken wychodzący od dostawcy OAuth (Google, Auth0, Keycloak, AWS Cognito), aby zrozumieć mechanikę bez zagłębiania się w dokumentację.
  • Eksploracja publicznych tokenów: badanie JWT znalezionego w dziennikach, w ciasteczku lub w przechwyconej wymianie OAuth.

Decoder vs Verifier: krytyczne rozróżnienie

Dwie operacje wydają się sąsiednie, ale nie mają nic wspólnego pod względem gwarancji bezpieczeństwa:

  • Dekodowanie JWT polega na podzieleniu ciągu na . i zastosowaniu odwrotnego Base64URL do dwóch pierwszych segmentów. To proste czytanie, w zasięgu każdego trzyliniowego skryptu. Żadna weryfikacja podpisu nie jest wykonywana.
  • Weryfikacja JWT polega na ponownym obliczeniu podpisu z nagłówka, payloadu i klucza, a następnie porównaniu wyniku z podpisem obecnym w tokenie. To to, co gwarantuje, że token nie został sfałszowany.

Praktyczny wniosek: dekodowanie nie znaczy zaufania. Dopóki podpis nie został zweryfikowany odpowiednim kluczem, zawartość payloadu może być całkowicie zmyślona. Do fazy zaufania użyj naszego JWT Verifier.

Jak korzystać

  1. Pobierz JWT do zbadania, na przykład z nagłówka Authorization: Bearer <jwt>, z ciasteczka sesji, z localStorage przeglądarki lub z dziennika aplikacji.
  2. Wklej cały ciąg w polu wprowadzania. Trzy segmenty muszą pozostać oddzielone kropkami.
  3. Narzędzie natychmiast wyświetla zdekodowany nagłówek w sformatowanym JSON, z algorytmem i typem.
  4. Payload jest następnie dekodowany i wyświetlany. Widzisz w nim wszystkie standardowe i custom claims.
  5. Narzędzie wskazuje też informację o podpisie (zadeklarowany algorytm, długość), bez jej weryfikacji.
  6. Aby potwierdzić, że token nie został sfałszowany, przejdź do naszego JWT Verifier z oczekiwanym kluczem publicznym lub sekretem.

Całe dekodowanie odbywa się w twojej przeglądarce w JavaScript: twój token nigdy nie jest wysyłany na nasze serwery.

JWT i bezpieczeństwo: pułapki do uniknięcia

NIGDY nie przechowuj wrażliwych danych w payloadzie podpisanego JWT.

Hasła, numery kart kredytowych, dane medyczne, sekrety API, krytyczne wewnętrzne identyfikatory: wszystko, co znajduje się w payloadzie, jest czytelne dla każdego, kto posiada token, w tym dla samego użytkownika przez narzędzia developerskie przeglądarki. Podpis niczego nie ukrywa, jedynie udowadnia, że emitent jest tym, za kogo się podaje.

Kilka złotych zasad dobrego używania JWT w produkcji:

  • Zawsze weryfikuj podpis po stronie serwera przed przyznaniem jakiegokolwiek prawa. Nasz JWT Verifier ilustruje dokładnie tę operację.
  • Preferuj RS256 lub ES256 nad HS256 dla publicznych API. Asymetryczny podpis unika dzielenia sekretu między emitentem a każdym konsumentem.
  • Zawsze respektuj claim exp. JWT bez wygaśnięcia lub z zbyt odległym wygaśnięciem to bomba zegarowa w razie wycieku.
  • Waliduj iss i aud po stronie serwera, aby uniknąć sytuacji, w której legalny token wyemitowany dla innej usługi jest błędnie akceptowany.
  • Odrzucaj alg: "none" po stronie weryfikacji. To klasyczna luka, która pozwala atakującemu sfałszować dowolny payload.
  • Utrzymuj krótkie czasy życia (na przykład 15 minut) i łącz z refresh tokenem dłuższym, ale unieważnialnym po stronie serwera.

Przykład zdekodowanego jetonu JWT

Oto typowy JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJuYW1lIjoiSm9obiIsImlhdCI6MTUxNjIzOTAyMn0.jrU9j8LZcRK2_BZjqXjU7lEpJbkqmXfTQIu9vT45j-I

Po zdekodowaniu oto jego zawartość:

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

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

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

Gdzie znaleźć JWT do skopiowania?

W praktyce JWT do odszyfrowania (w sensie dekodowania) pochodzi najczęściej z jednej z tych lokalizacji:

  • Ciasteczko HTTP: otwórz narzędzia developerskie (F12), zakładka Application lub Storage, następnie Cookies. Zlokalizuj ciasteczko o nazwie access_token, jwt, session lub podobne.
  • localStorage / sessionStorage: ten sam panel, sekcja Local Storage. Wiele SPA przechowuje tam swój token pod kluczem token lub auth.
  • Nagłówek Authorization: zakładka Network, wybierz żądanie API, odczytaj nagłówek Authorization: Bearer <jwt>. Skopiuj tylko część po Bearer .
  • Logi serwerowe: JWT czasem pojawia się w dziennikach bramy lub odwrotnego proxy (do unikania w produkcji, ale przydatne w debugowaniu).

Najczęściej zadawane pytania

Czy JWT jest szyfrowany czy jawny?

Podpisany JWT (format JWS) jest tylko zakodowany w Base64URL, nie szyfrowany. Każda osoba, która przechwytuje token, może odczytać payload w kilka sekund. Jeśli musisz przenosić naprawdę poufne dane w tokenie, użyj formatu JWE (JSON Web Encryption), który dodaje warstwę szyfrowania nad podpisem. W praktyce JWE pozostaje rzadkie: preferuje się nie umieszczać wrażliwych danych w tokenie i zachowywać krytyczne informacje w bazie po stronie serwera.

Jak unieważnić JWT przed jego wygaśnięciem?

To jeden ze słabych punktów JWT: z założenia serwer nie musi przechowywać stanu tokenu, więc też nie wie, jak oznaczyć go jako unieważniony. Istnieją trzy podejścia. Lista unieważnień: utrzymywanie po stronie serwera listy unieważnionych jti i konsultowanie jej przy każdym żądaniu. Krótkie czasy życia: emitowanie access tokenów ważnych 5 do 15 minut i używanie refresh tokenu unieważnialnego po stronie serwera do generowania nowych. Rotacja klucza podpisu: unieważnienie całej generacji tokenów przez zmianę klucza. Drugie podejście jest zdecydowanie najczęstsze.

Jaka jest różnica między JWT a klasyczną sesją?

Klasyczna sesja przechowuje nieprzezroczysty identyfikator po stronie klienta (zwykle w ciasteczku) i zachowuje wszystkie powiązane dane (użytkownik, prawa, wygaśnięcie) w pamięci lub bazie po stronie serwera. JWT, przeciwnie, przenosi te dane bezpośrednio w podpisanym tokenie. Zaleta JWT: serwer nie musi przechowywać sesji, co upraszcza skalowanie poziome i architekturę mikroserwisową. Wady: unieważnianie jest bardziej złożone, token jest objętościowo większy w każdym żądaniu, a najmniejszy wyciek ujawnia payload.

Różnica między JWT, JWS a JWE?

JWT (RFC 7519) to generyczny format tokenu. Można go zaimplementować na dwa konkretne sposoby: JWS (RFC 7515, JSON Web Signature), który ogranicza się do podpisywania payloadu, i JWE (RFC 7516, JSON Web Encryption), który go szyfruje. W praktyce, gdy mówimy „JWT" bez precyzji, mówimy prawie zawsze o JWS: podpisanym tokenie czytelnym dla wszystkich. JWE jest używany w kontekstach, gdzie poufność payloadu jest niezbędna, na przykład w niektórych zaawansowanych scenariuszach OpenID Connect.

Mój JWT nie jest akceptowany przez API, dlaczego?

Klasyczne przyczyny w kolejności częstości: token wygasł (sprawdź claim exp), nieprawidłowy podpis (sekretny lub publiczny klucz nie odpowiada temu używanemu przez emitenta), zły aud (token został wyemitowany dla innej usługi), zły iss (zadeklarowany emitent nie jest tym oczekiwanym), odrzucony algorytm (API wymaga na przykład RS256, a otrzymuje HS256), niezsynchronizowane zegary między emitentem a weryfikatorem (gra na exp i nbf). Zdekodowanie tokenu tym narzędziem pozwala już wyeliminować połowę hipotez, czytając bezpośrednio claims.

Jak wygenerować JWT?

Większość języków dysponuje dedykowaną biblioteką: jsonwebtoken w Node.js, PyJWT w Pythonie, lcobucci/jwt lub firebase/php-jwt w PHP, jjwt w Javie, golang-jwt/jwt w Go. Wszystkie przyjmują na wejściu obiekt payload, klucz i algorytm, a zwracają ciąg header.payload.signature gotowy do wysłania. Zdecydowanie odradza się ręczną implementację generowania: kryptografia ma zbyt wiele pułapek (porównania w niestałym czasie, niepoprawna obsługa alg: none itp.).

Czy dekoder akceptuje wygasły JWT?

Tak. Dekoder ogranicza się do wyświetlania zawartości tokenu bez wydawania osądu o jego czasowej ważności. Nie ocenia ani exp, ani nbf, ani podpisu. Jest to przydatne do zrozumienia, dlaczego token został odrzucony przez API: można porównać wartość exp z bieżącą godziną, aby potwierdzić, że jest dobrze wygasły.

Czy mój JWT jest ważny, jeśli dekoder go poprawnie wyświetla?

Nie. Wyświetlanie udowadnia tylko, że ciąg jest dobrze sformowany (trzy segmenty oddzielone kropkami, poprawne kodowanie Base64URL, prawidłowy JSON w nagłówku i payloadzie). Nie mówi nic o autentyczności tokenu. Całkowicie sfałszowany JWT może wyświetlić się bez błędu w dekoderze, dokładnie dlatego trzeba przekazać go do verifiera.

Przykładowe zapytanie

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

Schemat wejściowy

Pole Typ Wymagane Domyślnie
token text

Punkty końcowe

  • GET https://cdrn.fr/api/v1/tools - lista wszystkich dostępnych narzędzi
  • GET https://cdrn.fr/api/v1/tools/jwt-decoder - zwraca schemat dla tego narzędzia
  • POST https://cdrn.fr/api/v1/tools/jwt-decoder/execute - uruchamia to narzędzie z payloadem JSON