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.