jwt --- رموز JSON المميزة على الويب (JSON Web Tokens)¶
تنفيذ صغير لمعيار رمز JSON المميز على الويب (JWT) لأجل MicroPython. وJWT هو حاوية مدمجة وآمنة لاستخدامها في عناوين URL لحمولة JSON يوقّعها المُصدِر بحيث يستطيع المتحقّق كشف العبث وانتهاء الصلاحية.
هذا الإصدار المنقول إلى MicroPython صغير عن قصد:
يُدعَم HS256 فقط (HMAC مع SHA-256). أما خوارزميات RSA / ECDSA / EdDSA فغير منفّذة؛ ويجب أن يتشارك المُصدِر والمتحقّق مفتاحًا سريًا متماثلًا.
تُحترَم مطالبة
exp(انتهاء الصلاحية) الاختيارية. أما المطالبات المسجّلة الأخرى (nbf،iat،iss،aud،sub،jti) فتُمرَّر دون تغيير في الحمولة لكنها لا تُتحقَّق؛ ويتحقّق منها التطبيق إن كان معنيًا بها.لا توجد معالجة لتدوير المفاتيح، أو JWKS، أو قائمة الجمهور.
الدوال¶
- jwt.encode(payload: dict, key: bytes | str, algorithm: str = 'HS256') str¶
ترميز payload في رمز JWT موقَّع وإرجاع التسلسل المدمج الناتج (سلسلة
strمن الشكل"header.payload.signature"، كل مقطع مُرمَّز بترميز 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
سلسلة JWT المدمجة التي تنتجها
encode()(أو أي مُصدِر متوافق).- key
السر المشترك لـ HMAC. يجب أن يطابق المفتاح المستخدَم وقت الترميز.
- algorithms
قائمة الخوارزميات التي يقبلها المستدعي. يجب أن تكون
HS256موجودة، ويجب أن يكونalgفي ترويسة الرمز ضمن القائمة. القيمة الافتراضية هي["HS256"].
تطلق:
exceptions.InvalidAlgorithmError--HS256غير موجودة في algorithms، أو أنalgفي ترويسة الرمز أي شيء آخر غيرHS256.exceptions.InvalidTokenError-- الرمز مشوّه (لا ينقسم إلى ثلاثة مقاطع بترميز Base64-URL، أو فشل أحد المقاطع في فك الترميز / التحليل كـ JSON).exceptions.InvalidSignatureError-- لا يطابق التوقيع قيمة HMAC المُعاد حسابها على الترويسة والحمولة.exceptions.ExpiredSignatureError-- تحتوي الحمولة على مطالبةexpتقل قيمتها عن وقت Unix الحالي. يجب ضبط ساعة الكاميرا لكي يكون لهذا التحقّق معنى؛ انظرntptime.settime().
الاستثناءات¶
تُدرَج جميع الاستثناءات تحت سمة الوحدة jwt.exceptions.
- exception exceptions.PyJWTError¶
الفئة الأساسية لكل حالات فشل JWT. التقط هذه إذا لم تكن بحاجة إلى التمييز بين الحالات أدناه.
- exception exceptions.InvalidTokenError¶
الرمز غير صالح بنيويًا -- عدد خاطئ من المقاطع، أو مقطع يفشل في فك ترميز Base64، أو JSON يفشل في التحليل. فئة مشتقة من
exceptions.PyJWTError.
- exception exceptions.InvalidAlgorithmError¶
خوارزمية الرمز غير موجودة في القائمة التي يقبلها المستدعي، أو أن المستدعي طلب خوارزمية غير
HS256. فئة مشتقة منexceptions.PyJWTError.
- exception exceptions.InvalidSignatureError¶
لا يطابق توقيع الرمز قيمة HMAC المحسوبة من الترويسة والحمولة باستخدام المفتاح المُورَّد. فئة مشتقة من
exceptions.PyJWTError.
- exception exceptions.ExpiredSignatureError¶
مطالبة
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"])
يُستخدَم السر نفسه للتوقيع والتحقّق، لذا يجب أن يحمل المتحقّق المفتاح الذي استخدمه المُصدِر. أما الخدمات التي تكون فيها الكاميرا هي المُصدِر (التي توزّع الرموز على هاتف مقترن)، فاحتفظ بالسر على نظام ملفات الكاميرا وعامله كأي بيانات اعتماد أخرى طويلة الأمد -- انظر العمليات: المفاتيح والانتهاء واستكشاف الأخطاء وإصلاحها.