jwt — JSON Web Tokens

מימוש קטן של תקן ה-JSON Web Token (JWT) עבור MicroPython. JWT הוא מכל קומפקטי ובטוח-לכתובת (URL) עבור מטען JSON שהמנפיק חותם עליו כדי שהמאמת יוכל לזהות שיבוש ופקיעת תוקף.

פורט זה של MicroPython הוא קטן במכוון:

  • נתמך אך ורק HS256 (HMAC עם SHA-256). אלגוריתמי RSA / ECDSA / EdDSA אינם ממומשים; המנפיק והמאמת חייבים לחלוק מפתח סודי סימטרי.

  • תביעת ה-exp (פקיעת תוקף) האופציונלית נאכפת. תביעות רשומות אחרות (nbf, iat, iss, aud, sub, jti) מועברות ללא שינוי במטען אך אינן מאומתות; היישום בודק אותן אם הדבר חשוב לו.

  • אין טיפול בסבב מפתחות, JWKS או ברשימת קהל יעד (audience).

פונקציות

jwt.encode(payload: dict, key: bytes | str, algorithm: str = 'HS256') str

קידוד payload ל-JWT חתום והחזרת הסידור הקומפקטי המתקבל (מחרוזת str מהצורה "header.payload.signature", כאשר כל מקטע מקודד ב-Base64-URL).

payload

מילון (dict) של תביעות הניתן לסידור כ-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

מחרוזת ה-JWT הקומפקטית שהופקה על ידי encode() (או על ידי כל מנפיק תואם).

key

מפתח ה-HMAC הסודי המשותף. חייב להתאים למפתח שנעשה בו שימוש בעת הקידוד.

algorithms

רשימת האלגוריתמים שהקורא מוכן לקבל. HS256 חייב להיות נוכח, וה-alg שבכותרת ה-token חייב להיות ברשימה. ברירת המחדל היא ["HS256"].

מעלה:

חריגות

כל החריגות מקוננות תחת מאפיין המודול 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

תביעת ה-exp של ה-token היא בעבר. מחלקת משנה של 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"])

אותו סוד משמש לחתימה ולאימות, ולכן המאמת חייב להחזיק את המפתח שבו השתמש המנפיק. עבור שירותים שבהם המצלמה היא המנפיק (מחלקת tokens לטלפון מקושר), שמרו את הסוד במערכת הקבצים של המצלמה והתייחסו אליו כמו לכל אישור ארוך-טווח אחר – ראו תפעול: מפתחות, פקיעת תוקף ופתרון תקלות.

הערה

מודול זה מסתמך על hmac ו-hashlib, ששניהם מובנים במצלמה. אין צורך בתצורה חיצונית. מפתחות יכולים להיות בכל אורך, אך מבנה ה-HMAC שימושי ביותר עם מפתחות שאורכם לפחות כגודל הבלוק של SHA-256 (32 בתים).