jwt — JSON Web Tokens#
Niewielka implementacja standardu JSON Web Token (JWT) dla MicroPython. JWT to kompaktowy, bezpieczny dla adresów URL kontener na ładunek JSON, który wystawca podpisuje, aby weryfikator mógł wykryć manipulację i wygaśnięcie.
Ten port MicroPython jest celowo bardzo mały:
Obsługiwany jest tylko HS256 (HMAC z SHA-256). Algorytmy RSA / ECDSA / EdDSA nie są zaimplementowane; wystawca i weryfikator muszą współdzielić symetryczny klucz tajny.
Opcjonalne roszczenie
exp(wygaśnięcie) jest respektowane. Inne zarejestrowane roszczenia (nbf,iat,iss,aud,sub,jti) są przekazywane w ładunku bez zmian, ale nie są walidowane; aplikacja sprawdza je, jeśli mają dla niej znaczenie.Brak obsługi rotacji kluczy, JWKS ani list odbiorców.
Funkcje#
- jwt.encode(payload: dict, key: bytes | str, algorithm: str = 'HS256') str#
Koduje payload do podpisanego JWT i zwraca powstałą kompaktową serializację (
strw postaci"header.payload.signature", gdzie każdy segment jest zakodowany w Base64-URL).- payload
Słownik roszczeń możliwy do serializacji w formacie JSON. Standardowe roszczenia (
exp,iat,sub, …) są przekazywane dosłownie; niestandardowe klucze aplikacji są dozwolone.- key
Współdzielony sekret HMAC. Preferowany jest
bytes;strjest automatycznie kodowany w UTF-8.- algorithm
Musi być
"HS256"(wartość domyślna). Cokolwiek innego zgłaszaexceptions.InvalidAlgorithmError.
- jwt.decode(token: str, key: bytes | str, algorithms: list = ['HS256']) dict#
Weryfikuje podpis token oraz (jeśli jest obecne) jego roszczenie
expi zwraca zdekodowany słownik ładunku. Zgłasza podklasęexceptions.PyJWTErrorw przypadku jakiegokolwiek niepowodzenia – wywołujący zwykle przechwytuje klasę bazową.- token
Kompaktowy łańcuch JWT wytworzony przez
encode()(lub dowolnego kompatybilnego wystawcę).- key
Współdzielony sekret HMAC. Musi pasować do klucza użytego podczas kodowania.
- algorithms
Lista algorytmów, które wywołujący jest gotów zaakceptować. Musi być na niej obecny
HS256, a nagłówekalgtokenu musi znajdować się na tej liście. Domyślnie["HS256"].
Zgłasza:
exceptions.InvalidAlgorithmError–HS256nie znajduje się na liście algorithms lub nagłówekalgtokenu jest czymś innym niżHS256.exceptions.InvalidTokenError– token jest źle sformułowany (nie dzieli się na trzy segmenty Base64-URL lub segment nie daje się zdekodować / sparsować jako JSON).exceptions.InvalidSignatureError– podpis nie pasuje do ponownie obliczonego HMAC dla nagłówka i ładunku.exceptions.ExpiredSignatureError– ładunek zawiera roszczenieexp, którego wartość jest mniejsza niż bieżący czas uniksowy. Aby to sprawdzenie miało sens, zegar kamery musi być ustawiony; zobaczntptime.settime().
Wyjątki#
Wszystkie wyjątki są zagnieżdżone w atrybucie modułu jwt.exceptions.
- exception exceptions.PyJWTError#
Klasa bazowa dla każdego niepowodzenia JWT. Przechwyć ją, jeśli nie musisz rozróżniać między poniższymi przypadkami.
- exception exceptions.InvalidTokenError#
Token jest strukturalnie nieprawidłowy – niewłaściwa liczba segmentów, segment, którego nie udaje się zdekodować z Base64, lub JSON, którego nie udaje się sparsować. Podklasa
exceptions.PyJWTError.
- exception exceptions.InvalidAlgorithmError#
Algorytm tokenu nie znajduje się na liście akceptowanej przez wywołującego lub wywołujący zażądał algorytmu innego niż
HS256. Podklasaexceptions.PyJWTError.
- exception exceptions.InvalidSignatureError#
Podpis tokenu nie pasuje do HMAC obliczonego z nagłówka i ładunku przy użyciu podanego klucza. Podklasa
exceptions.PyJWTError.
- exception exceptions.ExpiredSignatureError#
Roszczenie
exptokenu odnosi się do przeszłości. Podklasaexceptions.PyJWTError. Aby to sprawdzenie miało sens, czas zegarowy kamery musi być ustawiony (za pomocąntptime.settime()).
Przykład#
Cykl wystawiania/weryfikacji z sekretem symetrycznym:
import jwt
import time
SECRET = b"keep-this-out-of-source-control"
payload = {
"sub": "kitchen-cam",
"role": "admin",
"exp": time.time() + 3600, # 1 hour from now
}
token = jwt.encode(payload, SECRET)
print("token:", token)
try:
claims = jwt.decode(token, SECRET)
except jwt.exceptions.PyJWTError as e:
print("rejected:", type(e).__name__)
else:
print("subject:", claims["sub"])
Ten sam sekret jest używany do podpisywania i weryfikacji, więc weryfikator musi posiadać klucz, którego użył wystawca. W przypadku usług, w których kamera jest wystawcą (wydając tokeny sparowanemu telefonowi), przechowuj sekret w systemie plików kamery i traktuj go jak każde inne długotrwałe poświadczenie – zobacz Operacje: klucze, wygasanie i rozwiązywanie problemów.