jwt --- JSON Web Token¶
JSON Web Token(JWT)標準在 MicroPython 上的精簡實作。JWT 是一種精簡且 URL 安全的容器,用於存放發行者所簽署的 JSON 酬載,讓驗證者能夠偵測竄改與過期。
此 MicroPython 移植版刻意保持極小:
僅支援 HS256(搭配 SHA-256 的 HMAC)。未實作 RSA / ECDSA / EdDSA 演算法;發行者與驗證者必須共用一把對稱式秘密金鑰。
會處理選用的
exp(過期)聲明。其他註冊聲明(nbf、iat、iss、aud、sub、jti)會原封不動地在酬載中傳遞,但不會被驗證;若應用程式在意這些聲明,則由其自行檢查。不處理金鑰輪替、JWKS 或受眾清單。
函式¶
- jwt.encode(payload: dict, key: bytes | str, algorithm: str = 'HS256') str¶
將 payload 編碼為已簽署的 JWT,並回傳產生的精簡序列化結果(一個形如
"header.payload.signature"的str,每個區段皆以 Base64-URL 編碼)。- payload
一個可序列化為 JSON 的聲明字典。標準聲明(
exp、iat、sub、...)會原封不動地傳遞;亦允許自訂的應用程式鍵。- key
共用的 HMAC 秘密金鑰。建議使用
bytes;str會自動以 UTF-8 編碼。- algorithm
必須是
"HS256"(預設值)。其他任何值都會擲出exceptions.InvalidAlgorithmError。
- jwt.decode(token: str, key: bytes | str, algorithms: list = ['HS256']) dict¶
驗證 token 的簽章以及(若存在)其
exp聲明,並回傳解碼後的酬載字典。任何失敗時都會擲出exceptions.PyJWTError的子類別——呼叫者通常會捕捉基底類別。- token
由
encode()(或任何相容的發行者)所產生的精簡 JWT 字串。- key
共用的 HMAC 秘密金鑰。必須與編碼時所用的金鑰相符。
- algorithms
呼叫者願意接受的演算法清單。
HS256必須存在,且 token 標頭中的alg必須在此清單中。預設為["HS256"]。
擲出例外:
exceptions.InvalidAlgorithmError--HS256不在 algorithms 中,或 token 標頭的alg是HS256以外的任何值。exceptions.InvalidTokenError-- token 格式不正確(無法切分為三個 Base64-URL 區段,或某個區段無法解碼/剖析為 JSON)。exceptions.InvalidSignatureError-- 簽章與針對標頭及酬載重新計算的 HMAC 不相符。exceptions.ExpiredSignatureError-- 酬載包含一個exp聲明,其值小於目前的 Unix 時間。必須設定相機的時鐘,此項檢查才有意義;請參閱ntptime.settime()。
例外¶
所有例外皆巢狀於模組屬性 jwt.exceptions 之下。
- exception exceptions.PyJWTError¶
每個 JWT 失敗的基底類別。若你不需要區分下列各種情況,可捕捉此類別。
- exception exceptions.InvalidTokenError¶
token 在結構上無效——區段數量錯誤、某個區段無法通過 Base64 解碼,或 JSON 無法剖析。為
exceptions.PyJWTError的子類別。
- exception exceptions.InvalidAlgorithmError¶
token 的演算法不在呼叫者接受的清單中,或呼叫者要求了
HS256以外的演算法。為exceptions.PyJWTError的子類別。
- exception exceptions.InvalidSignatureError¶
token 的簽章與使用所提供金鑰、根據標頭及酬載所計算出的 HMAC 不相符。為
exceptions.PyJWTError的子類別。
- exception exceptions.ExpiredSignatureError¶
token 的
exp聲明已過期。為exceptions.PyJWTError的子類別。必須設定相機的牆鐘時間(透過ntptime.settime()),此項檢查才有意義。
範例¶
一個對稱式秘密金鑰的簽發/驗證流程:
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"])
簽署與驗證使用相同的秘密金鑰,因此驗證者必須持有發行者所使用的金鑰。對於以相機作為發行者(向配對的手機發放 token)的服務,請將秘密金鑰保存在相機檔案系統上,並像對待任何其他長期憑證一樣對待它——請參閱 運維作業:金鑰、到期與疑難排解。