• jwt
  • auth
  • uwierzytelnianie
  • tożsamość
  • api
  • openid
  • oauth

Co to jest JSON Web Token (JWT)?

Zrozum podstawy JSON Web Token (JWT) w 5 minut.

Gao
Gao
Founder

JSON Web Token (JWT) jest szeroko stosowany we współczesnych aplikacjach internetowych i otwartych standardach, takich jak OpenID Connect, ułatwiając uwierzytelnianie i autoryzację. Chociaż oficjalny RFC 7519 służy jako niezbędne źródło informacji, może być trudny do zrozumienia dla początkujących. W tym artykule skupimy się na podstawowych koncepcjach JWT i przedstawimy je w przystępny sposób, z przykładami.

Dlaczego potrzebujemy JWT?

Obecnie dość powszechnym jest korzystanie z JSON do wymiany danych między dwiema stronami. Rozważmy obiekt JSON reprezentujący użytkownika:

sub to skrót od "subject", który jest standardowym roszczeniem w OpenID Connect, reprezentującym identyfikator użytkownika (ID użytkownika).

Jak możemy zagwarantować integralność tego obiektu JSON? Innymi słowy, jak możemy upewnić się, że dane nie zostały sfałszowane podczas transmisji? Powszechnym rozwiązaniem jest użycie cyfrowych podpisów. Na przykład możemy skorzystać z kryptografii z kluczem publicznym: serwer podpisuje obiekt JSON prywatnym kluczem, a klient może zweryfikować podpis za pomocą publicznego klucza serwera.

W skrócie, JWT oferuje standaryzowany sposób reprezentowania obiektu JSON i jego podpisu.

Format JWT

Ponieważ istnieje wiele algorytmów tworzenia podpisów cyfrowych, konieczne jest określenie algorytmu używanego do podpisania JWT. Jest to możliwe dzięki utworzeniu obiektu JSON:

alg to skrót od "algorithm", a typ to skrót od "type".

Zazwyczaj typ jest ustawiany na JWT wielkimi literami. W naszym przykładzie alg to HS256, co oznacza HMAC-SHA256 (wkrótce tego wyjaśnimy), i wskazuje, że używamy tego algorytmu do utworzenia podpisu.

Teraz mamy wszystkie składniki JWT:

  • JSON nagłówka: algorytm i typ
  • JSON ładunku: rzeczywiste dane
  • Podpis: podpis obejmujący nagłówek i ładunek

Jednak niektóre znaki, takie jak spacje i znaki nowej linii, nie są przyjazne dla transmisji sieciowej. Dlatego nagłówek i ładunek muszą być zakodowane w Base64URL. Typowy JWT wygląda tak:

. służy jako separator.

Połączmy wszystko razem i utworzymy JWT:

Nagłówek

JSON: {"alg":"HS256","typ":"JWT"}

Zakodowany w Base64URL: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Ładunek

JSON: {"sub":"foo","name":"John Doe"}

Zakodowany w Base64URL: eyJzdWIiOiJmb28iLCJuYW1lIjoiSm9obiBEb2UifQ

Podpis

W HMAC-SHA256, podpis jest tworzony za pomocą sekretu:

Na przykład, z sekretem some-great-secret, podpis staje się: XM-XSs2Lmp76IcTQ7tVdFcZzN4W_WcoKMNANp925Q9g.

JWT

Ostateczny JWT to:

Ten ważny JWT może być zweryfikowany przez dowolną stronę posiadającą sekret.

Wybierz algorytm podpisu

Jak wcześniej wspomniano, istnieje wiele algorytmów do tworzenia podpisów cyfrowych. Użyliśmy HS256 jako przykładu, ale może nie być wystarczająco silny, ponieważ sekret musi być udostępniony między stronami (np. klientem i serwerem).

W rzeczywistych scenariuszach klienci mogą obejmować publiczne aplikacje, takie jak aplikacje React, które nie mogą zapewnić bezpieczeństwa sekretu. W związku z tym preferowanym podejściem jest wykorzystanie kryptografii z kluczem publicznym (tj. kryptografii asymetrycznej) do podpisywania JWT. Zacznijmy od najpopularniejszego algorytmu: RSA.

RSA

RSA, czyli algorytm asymetryczny, korzysta z pary kluczy: klucza publicznego i klucza prywatnego. Klucz publiczny służy do weryfikacji podpisu, a klucz prywatny do podpisywania.

JSON nagłówka dla RSA wygląda tak:

RS256 oznacza RSA-SHA256, co oznacza, że podpis jest tworzony za pomocą algorytmu RSA i funkcji skrótu SHA256. Można również użyć RS384 i RS512 do tworzenia podpisów za pomocą funkcji skrótu SHA384 i SHA512, odpowiednio.

Podpis jest tworzony za pomocą klucza prywatnego:

Znowu możemy złożyć te części, aby utworzyć JWT, a ostateczny JWT wygląda tak:

Teraz klient może zweryfikować podpis bez znajomości klucza prywatnego.

ECDSA

Chociaż RSA jest szeroko stosowany, cierpi na większy rozmiar podpisów, czasami przekraczający łączną wielkość nagłówka i ładunku. Elliptic Curve Digital Signature Algorithm (ECDSA) to inny algorytm asymetryczny, który może tworzyć bardziej kompaktowe podpisy i jest bardziej wydajny.

Aby wygenerować klucz prywatny dla ECDSA, musimy wybrać krzywą. Jest to poza zakresem tego artykułu, ale więcej informacji znajdziesz tutaj.

JSON nagłówka dla ECDSA wygląda tak:

ES256 oznacza ECDSA-SHA256, co oznacza, że podpis jest tworzony za pomocą algorytmu ECDSA i funkcji skrótu SHA256. Można również użyć ES384 i ES512 do tworzenia podpisów za pomocą funkcji skrótu SHA384 i SHA512, odpowiednio.

Podpis jest tworzony za pomocą klucza prywatnego:

Ostateczny JWT zachowuje tę samą strukturę co RSA, ale z znacznie krótszym podpisem:

Weryfikacja JWT

Weryfikacja JWT jest prosta, jako proces odwrotny do tworzenia JWT:

  1. Podziel JWT na trzy części (nagłówek, ładunek i podpis) przy użyciu separatora ..
  2. Odkoduj nagłówek i ładunek za pomocą Base64URL.
  3. Zweryfikuj podpis za pomocą algorytmu określonego w nagłówku i klucza publicznego (dla algorytmów asymetrycznych).

Istnieje wiele bibliotek, które są dostępne do pomocy w weryfikacji JWT, takich jak jose dla Node.js i przeglądarek internetowych.

Podsumowanie

W tym artykule krótko wyjaśniliśmy podstawowe koncepcje JWT, oraz przedstawiliśmy, jak go tworzyć i weryfikować. Wiele szczegółów pozostało niezbadanych i omówimy je w przyszłych artykułach.

Logto wykorzystuje otwarte standardy, takie jak JWT i OpenID Connect, aby zabezpieczyć twoje aplikacje i API z uproszczonymi przepływami pracy dla każdego programisty. Jeśli jesteś zainteresowany, możesz go wypróbować za darmo (bez potrzeby podawania numeru karty kredytowej).