JSON Web Token (JWT) to otwarty standard (RFC 7519) służący do bezpiecznego przesyłania informacji pomiędzy stronami w postaci obiektu JSON. JWT jest szeroko stosowany do uwierzytelniania i autoryzacji w nowoczesnych aplikacjach internetowych i interfejsach API. W tym artykule szczegółowo przyjrzymy się działaniu tokenów JWT, z czego są wykonane i jak bezpiecznie z nich korzystać.
Co to jest JWT?
JWT (wymawiane „jot”) to kompaktowy, bezpieczny dla adresu URL sposób reprezentowania roszczeń między dwiema stronami. Token składa się z trzech części oddzielonych kropkami:Nagłówek. Ładunek. Podpis. Każda część jest zakodowana w formacie Base64URL.
W przeciwieństwie do tradycyjnych sesji, w których serwer przechowuje stan użytkownika, JWT to robiąbezpaństwowiec— wszystkie niezbędne informacje zawarte są w samym tokenie. To sprawia, że JWT idealnie nadaje się do systemów rozproszonych i architektur mikrousług.
Struktura tokena JWT
Chodnikowiec
Nagłówek zazwyczaj zawiera dwa pola: typ tokena (typ) i algorytm podpisu (alg). Najpopularniejszymi algorytmami są HS256 (HMAC z SHA-256) i RS256 (RSA z SHA-256).
Przykładowy nagłówek:
{
"alg": "HS256",
"typ": "JWT"
}
Ładunek
Ładunek zawiera oświadczenia — instrukcje dotyczące użytkownika i dodatkowe metadane. Istnieją trzy rodzaje roszczeń:
- Zarejestrowane roszczenia— pola standardowe:
iss(wydawca),exp(termin ważności),sub(temat),aud(publiczność),iat(czas tworzenia) - Roszczenia publiczne— są zdefiniowane w rejestrze IANA lub posiadają URI, aby uniknąć kolizji
- Prywatne roszczenia— dowolne pola uzgodnione pomiędzy stronami (np.
user_id,role)
Przykładowy ładunek:
{
"sub": "1234567890",
"name": "John Doe",
"role": "admin",
"iat": 1516239022,
"exp": 1516242622
}
Podpis
Podpis tworzony jest poprzez zakodowanie nagłówka i ładunku w Base64URL, połączenie ich kropką i podpisanie tajnym kluczem. Podpis gwarantuje, że token nie został zmodyfikowany od momentu utworzenia.
Dla HS256 wzór wygląda następująco:
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
Jak działa uwierzytelnianie JWT
Proces uwierzytelniania za pomocą JWT zwykle wygląda następująco:
- Login:Użytkownik wysyła swoje dane uwierzytelniające (adres e-mail + hasło) na serwer
- Generowanie tokena:Serwer sprawdza dane i jeśli są prawidłowe, tworzy JWT z niezbędnymi oświadczeniami
- Ochrona:Klient przechowuje token (zwykle w localStorage lub pliku cookie httpOnly)
- Wysyłanie żądań:Przy każdym żądaniu klient dodaje token do nagłówka
Authorization: Bearer <token> - Weryfikacja:Serwer weryfikuje podpis tokena i wyodrębnia dane użytkownika z ładunku
Zalety JWT
- Bezpaństwowiec:Serwer nie musi przechowywać sesji w bazie danych ani w pamięci
- Skalowalność:Idealny dla mikroserwisów - dowolna usługa może zweryfikować token
- Między domenami:JWT jest łatwy w użyciu między różnymi domenami i usługami
- Ścisłość:Niewielki rozmiar pozwala na przekazywanie tokena w adresach URL, parametrach POST czy nagłówkach
- Samowystarczalność:Wszystkie informacje potrzebne do autoryzacji zawarte są w tokenie
Bezpieczeństwo JWT: najlepsze praktyki
1. Zawsze ustalaj datę ważności
Nigdy nie twórz tokenów bezexpprawo. Zalecany czas życia tokena dostępu wynosi od 15 minut do 1 godziny. W przypadku dłuższych sesji użyj tokenów odświeżania.
2. Używaj plików cookie httpOnly
Zamiast localStorage lepiej przechowywać JWT w plikach cookie httpOnly, które nie są dostępne dla JavaScript. Chroni to przed atakami XSS. Dodatkowo zaznacz polaSecureISameSite.
3. Nie przechowuj wrażliwych danych w ładunku
Ładunek jest tylko zakodowany w Base64, a nie szyfrowany. Każdy może to rozszyfrować. Nigdy nie podawaj haseł, numerów kart kredytowych ani innych poufnych informacji.
4. Używaj niezawodnych algorytmów
Unikaj algorytmunone. Aby uzyskać podpis symetryczny, użyj HS256 z długim sekretem (minimum 256 bitów). Dla asymetrycznego — RS256 lub ES256.
5. Zweryfikuj wszystkie roszczenia
Podczas weryfikacji tokena zawsze sprawdzaj:exp(nie przeterminowany),iss(prawidłowy wydawca),aud(właściwa publiczność). Nie ufaj tokenowi tylko na podstawie prawidłowego podpisu.
6. Zaimplementuj unieważnienie tokena
Chociaż JWT jest bezstanowy, czasami trzeba unieważnić token (na przykład podczas wylogowania lub zmiany hasła). Aby to zrobić, użyj czarnej listy tokenów lub krótkiego życia z tokenami odświeżającymi.
Typowe błędy podczas pracy z JWT
- Brak weryfikacji podpisu— najniebezpieczniejszy błąd pozwalający na sfałszowanie tokena
- Używanie słabego sekretu— krótkie lub przewidywalne sekrety można wychwycić brutalną siłą
- Przechowywanie w localStorage— podatność na ataki XSS
- Data ważności jest za długa— zwiększa okno ataku, gdy token zostanie naruszony
- Transfer poprzez adres URL— token może dostać się do logów serwera i historii przeglądarki
JWT a sesje: kiedy czego używać
JWT jest najlepszy do:
- Aplikacje jednostronicowe (SPA) z osobnym API
- Architektura mikroserwisów
- Aplikacje mobilne
- Systemy z jednokrotnym logowaniem (SSO)
Tradycyjne sesje są lepsze dla:
- Serwerowe aplikacje webowe (Laravel, Rails, Django)
- Aplikacje, w których wymagane jest natychmiastowe cofnięcie dostępu
- Proste projekty bez skomplikowanej architektury
Sprawdź swoją wiedzę: Dekodowanie JWT
Chcesz zobaczyć, co kryje się w tokenie JWT? Skorzystaj z naszegoDekoder JWT— rozkłada token na części, pokazuje nagłówek, ładunek i sprawdza podpis. Jest to przydatne narzędzie dla programistów podczas debugowania uwierzytelniania.
Wniosek
Tokeny JWT to potężny mechanizm uwierzytelniania dla nowoczesnych aplikacji. Zapewniają autoryzację bezstanową, są łatwo skalowalne i działają pomiędzy różnymi usługami. Najważniejsze jest przestrzeganie zasad bezpieczeństwa: ustalanie daty ważności, stosowanie niezawodnych algorytmów, bezpieczne przechowywanie tokenów i weryfikowanie wszelkich roszczeń. Przy prawidłowym użyciu JWT znacznie upraszcza architekturę i poprawia wydajność aplikacji.