Aby zaimplementować warstwę autoryzacji i uwierzytelniania w rozproszonej architekturze, zazwyczaj wykorzystuje się systemy centralnego zarządzania tożsamością, takie jak OAuth 2.0, OpenID Connect lub korporacyjne dostawcy tożsamości (IdP). Uwierzytelnienie (ustalenie tożsamości) odbywa się za pośrednictwem zewnętrznego dostawcy, po czym wynik (zazwyczaj token) jest używany do autoryzacji (przyznawania uprawnień) we wszystkich usługach.
Zazwyczaj schemat działa w następujący sposób:
Przykład kodu weryfikacji tokena JWT w Pythonie przy użyciu biblioteki PyJWT:
import jwt from jwt.exceptions import InvalidTokenError def verify_jwt(token, public_key): try: payload = jwt.decode(token, public_key, algorithms=["RS256"]) return payload except InvalidTokenError: return None # przykład użycia user_info = verify_jwt(received_token, public_key) if user_info: # dostęp dozwolony pass else: # dostęp zabroniony pass
Kluczowe cechy:
Pytanie: Czy konieczne jest przechowywanie całej informacji o uprawnieniach użytkownika bezpośrednio w tokenie JWT?
Nie jest to konieczne. Aby zminimalizować rozmiar tokena, zwykle wprowadza się tylko identyfikator użytkownika i minimalny zestaw uprawnień/ról. Szczegółowe uprawnienia można uzyskać na żądanie na serwerze za pośrednictwem dodatkowych zapytań lub wczytywanych claimów profilu.
Pytanie: Czy tokeny odświeżające są obowiązkowym elementem wszystkich rozproszonych architektur?
Nie, tokeny odświeżające są wymagane tylko wtedy, gdy potrzebna jest długoterminowa sesja bez ponownego uwierzytelniania. W stateless API zazwyczaj działają tylko access tokens o krótkim czasie ważności, a logika odświeżania jest realizowana tylko dla klientów webowych lub mobilnych.
Pytanie: Czy sekcja payload w JWT może być zaszyfrowana?
Zgodnie z standardem JWT (RFC 7519) payload jest jedynie podpisywany, ale nie szyfrowany. Do szyfrowania używa się innego standardu — JWE (JSON Web Encryption). W przeciwnym razie każdy, kto posiada token, może odczytać payload (na przykład, przez jwt.io):
import jwt jwt.decode(token, options={"verify_signature": False})