JSON Web Tokens (JWT)

Temat, któremu chcemy się dzisiaj przyjrzeć to JWT, ostatnio bardzo często wykorzystywany w kontekście autoryzacji. Przyjrzymy się dokładniej czym jest JSON Web Tokens oraz w jaki sposób go generować i wykorzystywać w rzeczywistych przypadkach.

JWT – co to jest?

JWT (JSON Web Tokens) to otwarty standard (RFC 7519), który definiuje sposób wymiany danych między stronami w bezpieczny sposób poprzez obiekt JSON. Przesyłane informacje mogą być weryfikowane dzięki cyfrowemu podpisowi, który jest elementem tokenu.
Token JWT jest podpisany za pomocą sygnatury – algorytmem HMAC lub za pomocą klucza publicznego/prywatnego RSA lub ECDSA.

Kiedy JSON Web Tokens?

JWT może być wykorzystany przy:
1. Autoryzacji – JWT znajduje szerokie zastosowanie w autoryzacji kiedy jedna ze stron chce przyznać dostęp drugiej do zasobów i serwisów, a później bez przechowywania stanu po swojej stronie weryfikować czy dostęp powinien być możliwy.

2. Transmisji danych – Kiedy chcemy przesłać pomiędzy stronami informacje i potrzebujemy mieć pewność, że nadawca jest tym za kogo się podaje i dane które wysyła nie zostały zmienione. Możemy to zweryfikować właśnie dzięki cyfrowemu podpisowi, które jest częścią JWT.

Struktura JWT

JWT w swojej wynikowej postaci (jako token) składa się z trzech części oddzielonych od siebie kropkami.

Przykład:
aaaa.bbbb.cccc

Te części to kolejno:
• Nagłówek (Header)
• Zawartość (Payload)
• Sygnatura (Signature)

1. Nagłówek (Header)

Nagłówek zawiera informację o rodzaju tokena – JWT oraz o tym jakiego algorytmu używamy – HMAC SHA256 lub RSA.
Przykład:

{
  "alg": "HS512",
  "typ": "JWT"
}

Obiekt JSON w postaci wynikowej jest zmieniany na zapis w Base64.

2. Zawartość (Payload)

Ta część odpowiedzialna jest za przechowywanie danych, które chcemy przesyłać w tokenie. JWT wyróżnia trzy typy informacji zawartych w payload: Registered claims, Public claims oraz Private claims.
Oprócz danych identyfikacyjnych tokena oraz informacji o dacie ważności i kontekstu, w payload umieszczamy dane związane z rolą użytkownika, dostępem do zasobów, ustawieniami itp.

Przykład:

{
  "customerId": "123",
  "role": "customer"
}

Tak jak w przypadku nagłówka, payload też kodowany jest w formacie Base64.

3. Sygnatura (Signature)

Sygnatura jest podpisem cyfrowym potwierdzającym autentyczność danych zawartych w tokenie. Walidacja sygnatury daje nam pewność, że nadawca jest tym za kogo się podaje.
Pewność tą zyskujemy dzięki metodzie budowania sygnatury. Przyjrzyjmy się temu bliżej:

Jeśli wybierzemy algorytm haszowania np. HMAC SHA256 to sygnatura tworzoną będzie w następujący sposób:

HMACSHA256(base64UrlEncode(header) + ’.’ + base64UrlEncode(payload), secret)

Gdzie secret to nasze hasło potrzebne do haszowania sygnatury. Musimy pamiętać o tym, że secret powinien być długi i składać się z różnych znaków, ponieważ łamiąc secret jesteśmy w stanie podszyć się pod serwis autoryzacyjny i wprowadzić swoje dane w payload.
Przykład implementacji algorytmu generowania tokenu JWT napisany w NodeJS. W przykładzie skorzystamy z implementacji algorytmu haszowania i kodowania base64Url poprzez zewnętrzne biblioteki.

const hmacSha256 = require('crypto-js/hmac-sha256');
const base64url = require('base64url');

const header = {
    typ: 'JWT',
    alg: 'HS256'
};

const payload = {
    userId: 123,
    role: 'customer'
};

const secret = 'secret password';

const jwtToken = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
const signature = base64url.encode(hmacSha256(jwtToken, secret).toString());
const jwtSignedToken = jwtToken + '.' + signature;

console.log(jwtSignedToken);

function base64UrlEncode(item) {
    return base64url.encode(JSON.stringify(item));
};

Zastosowanie

JSON Web Tokens można wykorzystać np. do budowy serwisu autoryzacyjnego, w którym chcemy uwierzytelniać użytkowników aplikacji – przykład:

Tworzenie serwisu z możliwością autoryzowania użytkowników:

1. Budujemy back-end naszej aplikacji i udostępniamy REST API naszym aplikacją klienckim.
2. Tworzymy aplikację kliencką, która komunikuję się poprzez REST API z częścią back-endową.
3. Dołączamy serwis autoryzacyjny, za pomocą którego aplikacje klienckie będą uzyskiwały tokeny JWT a back-end będzie w stanie sprawdzić czy użytkownik powinien dostać dostęp do żądanego zasobu.

wpis tech

Podsumowanie

W tym wpisie omówiliśmy strukturę JWT i zasadę budowania tokenów. Widzimy również zastosowanie tego standardu i w jak łatwy sposób jesteśmy w stanie zarządzać uprawnieniami i autoryzacją użytkowników.

Źródło: https://jwt.io/

Autorem tekstu jest Kamil Moroń.

0 0 votes
Article Rating
Subscribe
Powiadom o
2 komentarzy
najstarszy
najnowszy oceniany
Inline Feedbacks
View all comments
Andrzej
Andrzej
5 lat temu

Kamil zajebisty tekst. Brakuje mi tylko info o tym skąd się bierze secret?