abclinuksa.pl

Token JWT - Jak działa i jak go bezpiecznie wdrożyć?

Dawid Grabowski.

24 lutego 2026

Schemat tworzenia tokenu JWT: nagłówek, ładunek i podpis połączone w jeden ciąg.

JSON Web Token, znany szerzej jako JWT, to otwarty standard, który zrewolucjonizował sposób, w jaki bezpiecznie przesyłamy informacje między różnymi systemami. Zdefiniowany w RFC 7519, JWT pozwala na kompaktowe i samowystarczalne przekazywanie danych w formie obiektu JSON, który jest dodatkowo cyfrowo podpisany. Ten podpis gwarantuje, że dane nie zostały zmienione po drodze i pochodzą z zaufanego źródła. W świecie, gdzie aplikacje stają się coraz bardziej rozproszone, a komunikacja między serwisami jest kluczowa, JWT oferuje eleganckie rozwiązanie problemów związanych z tradycyjnymi mechanizmami uwierzytelniania, takimi jak sesje oparte na ciasteczkach. Jego kompaktowość i samowystarczalność sprawiają, że jest idealnym kandydatem do zastosowań w nowoczesnych architekturach, od REST API po aplikacje mobilne i Single Page Applications (SPA).

Kluczowe informacje o JSON Web Token

  • JWT to otwarty standard do bezpiecznego przesyłania informacji między stronami jako cyfrowo podpisany obiekt JSON.
  • Składa się z trzech części: nagłówka, ładunku i sygnatury, oddzielonych kropkami.
  • Umożliwia bezstanową autoryzację, co jest kluczowe dla skalowalności i architektury mikroserwisów.
  • Główne zagrożenia to kradzież tokenu (np. przez XSS) i brak łatwego unieważniania.
  • Idealny do REST API, aplikacji mobilnych i SPA, gdzie tradycyjne sesje są mniej efektywne.

Diagram przepływu danych, gdzie token JWT jest używany do uwierzytelniania między Microsoft 365 Copilot a CEA host.

Token JWT: Co to jest i dlaczego stał się standardem w nowoczesnych aplikacjach

JSON Web Token (JWT) to otwarty standard, zdefiniowany w RFC 7519, który stanowi sposób na bezpieczne przesyłanie informacji między stronami w formie obiektu JSON. Kluczową cechą JWT jest jego kompaktowość i samowystarczalność wszystkie niezbędne informacje są zawarte w samym tokenie, który jest dodatkowo cyfrowo podpisany. Ten podpis zapewnia integralność danych, czyli gwarantuje, że nie zostały one zmodyfikowane podczas transmisji, oraz ich autentyczność, potwierdzając, że pochodzą z zaufanego źródła. W przeciwieństwie do tradycyjnych sesji opartych na ciasteczkach, które wymagają od serwera przechowywania stanu sesji dla każdego użytkownika, JWT umożliwia implementację bezstanowej autoryzacji. Oznacza to, że serwer nie musi pamiętać informacji o zalogowanych użytkownikach między żądaniami, co znacząco upraszcza skalowanie aplikacji i jest fundamentalne dla architektury mikroserwisowej. Niezależność od platformy, łatwość użycia i wsparcie dla różnych algorytmów kryptograficznych sprawiły, że JWT stał się de facto standardem w nowoczesnym rozwoju aplikacji, od REST API po aplikacje mobilne.

Schemat przedstawia proces weryfikacji tokenu JWT. Po żądaniu dostępu, token jest weryfikowany, dekodowany, a jego integralność sprawdzana.

Anatomia tokenu JWT: Co dokładnie kryje się za trzema częściami oddzielonymi kropką

Każdy token JWT składa się z trzech części, które są oddzielone kropkami: nagłówka, ładunku i sygnatury. Każda z tych części jest kodowana przy użyciu Base64Url, co sprawia, że token jest czytelny i łatwy do przesyłania.

  • Nagłówek (Header): Ta część tokenu zazwyczaj zawiera informacje o typie tokenu, który zawsze powinien być `"JWT"`, oraz o algorytmie kryptograficznym używanym do podpisania tokenu. Typowe algorytmy to `HS256` (HMAC z algorytmem SHA-256), który używa wspólnego sekretnego klucza, oraz `RS256` (RSA z algorytmem SHA-256), który wykorzystuje parę kluczy: prywatny do podpisywania i publiczny do weryfikacji.
  • Ładunek (Payload): Zawiera tak zwane "claims" czyli stwierdzenia dotyczące encji (najczęściej użytkownika) i dodatkowe metadane. Claims można podzielić na trzy kategorie:
    • Zarejestrowane oświadczenia (Registered claims): Są to predefiniowane klucze, które nie są obowiązkowe, ale zalecane, aby zapewnić spójność i użyteczność. Przykłady to `iss` (wystawca tokenu), `exp` (czas wygaśnięcia tokenu), `sub` (podmiot, czyli identyfikator użytkownika), `aud` (odbiorca) czy `iat` (czas wydania tokenu).
    • Publiczne oświadczenia (Public claims): Są to niestandardowe oświadczenia, które mogą być używane przez organizacje lub użytkowników. Aby uniknąć konfliktów, powinny być definiowane w URI.
    • Prywatne oświadczenia (Private claims): Są to niestandardowe oświadczenia tworzone przez strony w celu wymiany informacji. Nie są one rejestrowane ani w żaden sposób standaryzowane, więc należy zachować ostrożność przy ich używaniu.
  • Sygnatura (Signature): Jest to kluczowy element zapewniający bezpieczeństwo. Sygnatura jest tworzona poprzez zakodowanie nagłówka i ładunku, a następnie podpisanie ich przy użyciu sekretnego klucza (dla algorytmów symetrycznych) lub klucza prywatnego (dla algorytmów asymetrycznych). Serwer, który otrzymuje token, używa klucza publicznego (lub tego samego sekretnego klucza) do zweryfikowania sygnatury. Jeśli sygnatura jest poprawna, oznacza to, że nagłówek i ładunek nie zostały zmienione od momentu wydania tokenu, a token został wygenerowany przez kogoś, kto posiada odpowiedni klucz.

Schemat przepływu danych: użytkownik, aplikacja, deweloper, API (z tokenem JWT), zespół API, backend. Sekcje: ochrona przed zagrożeniami, kontrola dostępu, samoobsługa i SSO, zarządzanie bezpieczeństwem, bezpieczeństwo danych.

Mechanizm działania JWT krok po kroku: Od logowania do autoryzowanego dostępu

Proces wykorzystania JWT do autoryzacji jest zazwyczaj płynny i intuicyjny dla użytkownika końcowego, a jednocześnie efektywny dla systemu. Oto jak wygląda typowy przepływ:

  1. Krok 1: Użytkownik się loguje serwer generuje i podpisuje token: Kiedy użytkownik podaje swoje dane uwierzytelniające (np. login i hasło) do aplikacji, serwer weryfikuje ich poprawność. Po pomyślnym uwierzytelnieniu, serwer tworzy token JWT. W tym celu najpierw generuje nagłówek i ładunek zawierający informacje o użytkowniku (np. jego ID, role, czas wygaśnięcia tokenu). Następnie, używając tajnego klucza lub klucza prywatnego, serwer podpisuje te dane, tworząc sygnaturę. Cały token nagłówek, ładunek i sygnatura jest następnie zwracany do klienta.

  2. Krok 2: Klient przechowuje token gdzie i jak robić to bezpiecznie?: Po otrzymaniu tokenu JWT od serwera, klient (np. przeglądarka internetowa) musi go gdzieś przechować, aby móc go używać w kolejnych żądaniach. Istnieją dwie główne metody przechowywania:

    • `localStorage` lub `sessionStorage`: Są to mechanizmy przeglądarki pozwalające na przechowywanie danych w postaci klucz-wartość. Zaletą jest łatwy dostęp do danych z poziomu JavaScript. Wadą jest jednak podatność na ataki typu Cross-Site Scripting (XSS), ponieważ złośliwy skrypt działający na stronie może uzyskać dostęp do tych danych.
    • `HttpOnly cookie`: To specjalny typ ciasteczka, który jest dostępny tylko dla serwera i nie można go odczytać z poziomu JavaScript. Jest to znacznie bezpieczniejsza opcja, ponieważ chroni token przed kradzieżą przez ataki XSS. Wymaga jednak odpowiedniej konfiguracji serwera i może być nieco bardziej skomplikowane w zarządzaniu w przypadku aplikacji front-endowych działających na innej domenie niż API.
    Wybór metody zależy od wymagań bezpieczeństwa i architektury aplikacji. Generalnie, `HttpOnly cookie` są preferowane ze względów bezpieczeństwa.
  3. Krok 3: Dostęp do chronionych zasobów z nagłówkiem `Authorization: Bearer`: Kiedy klient chce uzyskać dostęp do zasobu chronionego przez autoryzację, musi dołączyć token JWT do swojego żądania. Najczęściej odbywa się to poprzez dodanie nagłówka `Authorization`, którego wartość ma format `Bearer `. Na przykład: `Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...`. Schemat `Bearer` oznacza, że token zawiera upoważnienie do dostępu do zasobu.

  4. Krok 4: Serwer weryfikuje token szybka i bezstanowa walidacja przy każdym żądaniu: Po otrzymaniu żądania z tokenem JWT, serwer musi je zweryfikować. Pierwszym krokiem jest sprawdzenie, czy token ma poprawny format i czy sygnatura jest prawidłowa. Serwer używa do tego klucza publicznego (lub sekretnego klucza, jeśli używany jest algorytm symetryczny) do odszyfrowania sygnatury i porównania jej z nagłówkiem i ładunkiem. Jeśli sygnatura jest poprawna, serwer może zaufać informacjom zawartym w ładunku i udzielić użytkownikowi dostępu do żądanego zasobu. Co ważne, serwer nie musi odpytywać bazy danych ani przechowywać żadnych informacji o stanie sesji cała niezbędna wiedza znajduje się w samym tokenie. Ta bezstanowość jest kluczowa dla skalowalności, ponieważ pozwala na łatwe rozproszenie obciążenia na wiele instancji serwerów.

Bezpieczeństwo JWT: Najczęstsze pułapki i jak ich unikać w praktyce

Choć JWT oferuje wiele zalet związanych z bezpieczeństwem i skalowalnością, jego niewłaściwa implementacja może prowadzić do poważnych luk. Zrozumienie potencjalnych zagrożeń jest kluczowe dla bezpiecznego stosowania tego standardu.

  • Podatność `alg: none`: Jedną z najbardziej niebezpiecznych luk jest możliwość ustawienia w nagłówku algorytmu na `"alg": "none"`. W takim przypadku serwer może uznać token za prawidłowy bez weryfikacji sygnatury, ponieważ teoretycznie nie została ona użyta. Atakujący może to wykorzystać, modyfikując ładunek tokenu (np. zmieniając ID użytkownika na administratora) i wysyłając go do serwera z nagłówkiem `"alg": "none"`. Aby się przed tym chronić, serwer powinien zawsze odrzucać tokeny z tym algorytmem lub jawnie konfigurować listę dozwolonych algorytmów, nigdy nie dopuszczając `none`.
  • Kradzież tokenu przez ataki XSS: Jak wspomniano wcześniej, jeśli token JWT jest przechowywany w `localStorage`, atakujący może wykorzystać lukę Cross-Site Scripting (XSS) do wykonania złośliwego kodu JavaScript na stronie użytkownika. Ten kod może następnie odczytać token z `localStorage` i wysłać go atakującemu, co umożliwi przejęcie sesji użytkownika. Używanie `HttpOnly cookie` znacząco redukuje to ryzyko, ponieważ JavaScript nie ma do nich dostępu.
  • Wyciek sekretnego klucza: Klucz używany do podpisywania tokenów (zarówno sekretny dla algorytmów symetrycznych, jak i klucz prywatny dla asymetrycznych) jest absolutnie krytyczny. Jeśli atakujący zdobędzie ten klucz, może tworzyć własne, fałszywe tokeny JWT z dowolnymi danymi, które serwer uzna za autentyczne. Klucze te powinny być przechowywane w bezpiecznym miejscu, najlepiej jako zmienne środowiskowe lub w dedykowanych systemach zarządzania sekretami, a nie w kodzie źródłowym aplikacji.
  • Problem unieważnienia tokenu: Standard JWT zakłada, że token jest ważny do momentu wygaśnięcia określonego w ładunku. Oznacza to, że jeśli token zostanie skradziony, atakujący może go używać aż do jego wygaśnięcia. Natychmiastowe wylogowanie użytkownika, np. po zmianie hasła, staje się problematyczne. Aby zaradzić temu problemowi, stosuje się kilka strategii:
    • Ustawianie bardzo krótkiego czasu życia dla głównych tokenów (np. 15-60 minut).
    • Wprowadzenie mechanizmu "refresh tokens" dłużej żyjących tokenów, które służą do odświeżania głównych tokenów, ale są przechowywane w bezpieczniejszy sposób i mogą być łatwiej unieważnione.
    • Utrzymywanie po stronie serwera listy unieważnionych tokenów (tzw. blacklist), do której dodawane są tokeny po wylogowaniu lub zmianie hasła. Weryfikacja tokenu wymaga wtedy sprawdzenia zarówno sygnatury, jak i obecności tokenu na tej liście.
  • Czy w ładunku (payload) można przechowywać wrażliwe dane? Absolutnie nie. Ładunek tokenu JWT jest kodowany przy użyciu Base64, a nie szyfrowany. Oznacza to, że każdy, kto przechwyci token, może łatwo odczytać jego zawartość. Dlatego też nigdy nie należy przechowywać w ładunku JWT wrażliwych informacji, takich jak hasła, numery kart kredytowych czy dane osobowe, które nie powinny być widoczne dla nikogo poza zaufanym odbiorcą.

JWT w praktyce: Kiedy warto go używać, a kiedy wybrać inne rozwiązanie

Decyzja o zastosowaniu JWT powinna być podejmowana świadomie, biorąc pod uwagę specyfikę projektu. JWT doskonale sprawdza się w scenariuszach, gdzie wymagana jest skalowalność i bezstanowość. Jest to idealne rozwiązanie dla REST API, które często obsługują ruch z różnych klientów (przeglądarki, aplikacje mobilne, inne serwisy). W architekturze mikroserwisowej, gdzie komunikacja między niezależnymi usługami jest kluczowa, JWT pozwala na łatwe przekazywanie informacji o autoryzacji bez konieczności centralnego zarządzania stanem sesji. Podobnie w przypadku aplikacji mobilnych i Single Page Applications (SPA), gdzie tradycyjne sesje oparte na ciasteczkach mogą być problematyczne ze względu na ograniczenia przeglądarek i konieczność obsługi wielu domen.

Jednak JWT nie jest panaceum. Tradycyjne sesje, choć stanowe, oferują większą kontrolę nad stanem użytkownika i łatwiejsze mechanizmy unieważniania tokenów. Jeśli aplikacja jest prosta, monolityczna i nie wymaga ekstremalnej skalowalności, a prostota zarządzania sesją jest priorytetem, tradycyjne sesje mogą być lepszym wyborem. Warto również wspomnieć o nowszych alternatywach, takich jak PASETO (Platform-Agnostic Security Tokens), które są zaprojektowane z myślą o większym bezpieczeństwie i prostocie niż JWT, czy Branca, która skupia się na szyfrowaniu i kompaktowości. Wybór zależy od konkretnych potrzeb projektu, wymagań bezpieczeństwa i preferencji zespołu deweloperskiego.

Implementacja JWT: Narzędzia i biblioteki, które ułatwią Ci pracę

Na szczęście, implementacja JWT nie musi być skomplikowana. Społeczność open-source stworzyła bogaty ekosystem bibliotek i narzędzi, które znacząco ułatwiają pracę z tym standardem w niemal każdym popularnym języku programowania. Oto kilka przykładów:

  • Node.js: Biblioteka `jsonwebtoken` jest niezwykle popularna i oferuje proste API do tworzenia i weryfikacji tokenów JWT.
  • Python: Pakiet `PyJWT` jest standardem w świecie Pythona, zapewniając solidne wsparcie dla algorytmów JWT.
  • Java: W ekosystemie Spring, biblioteka Spring Security oferuje zaawansowane mechanizmy do integracji JWT z aplikacjami.
  • .NET: Biblioteka `System.IdentityModel.Tokens.Jwt` jest oficjalnym narzędziem Microsoftu do pracy z JWT w środowisku .NET.

Wyobraźmy sobie, jak mogłoby wyglądać generowanie i walidacja tokenu w Node.js przy użyciu biblioteki `jsonwebtoken`. Proces generowania tokenu po udanym zalogowaniu użytkownika wyglądałby mniej więcej tak: serwer otrzymuje dane użytkownika, tworzy obiekt z informacjami do umieszczenia w ładunku (np. `{ userId: '123', role: 'admin' }`) i wywołuje funkcję `jwt.sign(payload, secretKey, { expiresIn: '1h' })`. Funkcja ta zwraca gotowy, podpisany token JWT. Z kolei przy każdym żądaniu do chronionego zasobu, serwer odbiera token z nagłówka `Authorization`, a następnie weryfikuje jego poprawność za pomocą `jwt.verify(token, secretKey, (err, decoded) => { ... })`. Jeśli weryfikacja przebiegnie pomyślnie, obiekt `decoded` będzie zawierał informacje z ładunku tokenu, gotowe do użycia.

Aby ułatwić analizę i debugowanie tokenów JWT, niezastąpionym narzędziem jest strona jwt.io. Pozwala ona na wklejenie tokenu i natychmiastowe zobaczenie jego struktury (nagłówka i ładunku) oraz weryfikację sygnatury przy użyciu podanego sekretnego klucza. To nieoceniona pomoc dla każdego dewelopera pracującego z JWT.

Źródło:

[1]

https://pl.wikipedia.org/wiki/JSON_Web_Token

[2]

https://jwt.io/introduction

[3]

https://cyberfolks.pl/slownik/jwt/

[4]

https://devszczepaniak.pl/json-web-token/

[5]

https://nofluffjobs.com/pl/log/praca-w-it/poczatki-w-it/jwt-token-co-to-jest-jak-go-uzywac-w-autoryzacji/

FAQ - Najczęstsze pytania

JWT to otwarty standard (RFC 7519) do bezpiecznego przesyłania informacji jako JSON. Jest bezstanowy, składa się z nagłówka, ładunku i sygnatury, a podpis zapewnia autentyczność i integralność.

Nagłówek i ładunek są kodowane, a sygnatura tworzona kluczem (sekretnym lub prywatnym). Weryfikacja potwierdza, że token nie został zmieniony i pochodzi od zaufanego źródła.

W REST API, SPA i aplikacjach mobilnych, gdzie liczy się skalowalność i bezstanowość. Można stosować z mechanizmami odświeżania tokenów (refresh tokens).

Unikaj algorytmu "none", używaj dozwolonych algorytmów. Stosuj HttpOnly cookies, krótkie TTL, bezpieczne przechowywanie kluczy i listy unieważnionych tokenów.

Oceń artykuł

Ocena: 0.00 Liczba głosów: 0
rating-outline
rating-outline
rating-outline
rating-outline
rating-outline

Tagi

token jwt
/
jak działa json web token
/
budowa jwt nagłówek ładunek sygnatura
/
bezpieczeństwo jwt unieważnianie tokenów
/
jwt vs sesje porównanie
/
jak zaimplementować jwt w node.js
Autor Dawid Grabowski
Dawid Grabowski
Jestem Dawid Grabowski, specjalizującym się w systemach Linux, bezpieczeństwie oraz oprogramowaniu. Od ponad pięciu lat analizuję rynek technologiczny, co pozwoliło mi zdobyć głęboką wiedzę na temat najnowszych trendów i rozwiązań w tych dziedzinach. Moim celem jest uproszczenie skomplikowanych zagadnień technicznych, aby każdy mógł zrozumieć kluczowe aspekty związane z bezpieczeństwem i efektywnym wykorzystaniem systemów Linux. W swojej pracy stawiam na obiektywną analizę i rzetelne fakt-checking, co sprawia, że moje teksty są wiarygodnym źródłem informacji. Zawsze dążę do dostarczania czytelnikom aktualnych i dokładnych treści, które mogą pomóc w podejmowaniu świadomych decyzji dotyczących technologii. Moim priorytetem jest budowanie zaufania poprzez transparentność i zaangażowanie w dostarczanie wartościowych informacji.

Napisz komentarz