ما هو التوكن؟
قبل تقديم التوكنات غير الشفافة، من المهم أن نفهم ما هو التوكن:
تُستخدم التوكنات لتمثيل ونقل المعلومات الآمنة بين الأطراف، وتدعم الغالبية العظمى من عمليات المصادقة (authentication) والتفويض (authorization) التي تحدث وراء الكواليس على الإنترنت. النوعان الأكثر شيوعًا من التوكنات في خدمات الويب هما RFC 7519: JSON Web Tokens (JWT) والتوكنات غير الشفافة.
ما هو التوكن غير الشفاف؟
التوكنات غير الشفافة هي توكنات بتنسيق مملوك لا يمكنك الوصول إليه وعادةً ما تحتوي على بعض المعرفات التي تشير إلى معلومات في التخزين الدائم للخادم.
التوكن غير الشفاف هو شكل يمكن أن يتخذه التوكن، ويمكن أن توجد توكنات الوصول (access tokens) وتوكنات التحديث (refresh tokens) كتوكينات غير شفافة. يتم تحديد تنسيق التوكن غير الشفاف بواسطة مُصدِره، وعادةً ما يكون سلسلة من الأرقام و/أو الأحرف التي تُستخدم لمساعدة المُصدر في استرجاع وتحديد معلومات معينة في قاعدة البيانات. هنا مثال على التوكن غير الشفاف:
M-oxIny1RfaFbmjMX54L8Pl-KQEPeQvF6awzjWFA3iq
من جهة أخرى، يعتبر JWT تنسيق توكن شائع آخر. هو سلسلة JSON تحتوي على كافة الclaims والمعلومات بالإضافة إلى توقيع من المُصدر. بشكل افتراضي، لا يتم تشفيره، على الرغم من أنه يمكن تشفيره باستخدام معيار JSON Web Encryption (JWE). ورغم أن JWT عادةً غير مشفرة، فإن ذلك لا يضر بأمانها — وجود التوقيع يضمن سلامة محتويات التوكن، مما يسمح بالثقة الكاملة في البيانات داخل JWT.
على عكس JWT، التي تحتوي على كافة المعلومات اللازمة للتحقق منها مباشرة في المورد المحمي، لا يمكن التحقق من التوكنات غير الشفافة مباشرة بواسطة المورد. بدلاً من ذلك، يتطلبون التحقق من قِبَل مُصدر التوكن غير الشفاف (عادةً الخادم التفويضي). هذه العملية للتحقق تُعرف عادةً باسم استقصاء التوكن (token introspection).
ما هو JWT؟
على النقيض من التوكنات غير الشفافة، يعتبر JWT توكن مكتفي ذاتيًا وغير معتمد على الحالة ينقل المعلومات بترتيب وصيغة قابلة للقراءة.
يتكون JWT من ثلاثة أجزاء: العنوان (header)
، والحمولة (payload)
، والتوقيع (signature)
، وكلها مشفرة بصيغة Base64URL.
إليك مثال على JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
- يحتوي
العنوان (header)
على معلومات حول نوع التوكن والخوارزمية المستخدمة للتوقيع. على سبيل المثال،{"alg": "HS256", "typ": "JWT"}
. - تحتوي قسم
الحمولة (payload)
على الclaims—قطع من المعلومات حول المستخدم أو التفويض—مثل معرف المستخدم، وقت الانتهاء، النطاقات. لأن هذه البيانات مشفرة ولكن غير مشفرة، يستطيع أي شخص يملك التوكن فك تشفيرها لرؤية الclaims، على الرغم من أنه لا يمكنهم تغييرها دون إبطال التوقيع. بناءً على المواصفات وتكوين الخادم التفويضي، يمكن تضمين العديد من الclaims في الحمولة. هذا يمنح التوكن طبيعته المكتفية ذاتيًا. على سبيل المثال،{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}
. - يتم إنشاء
التوقيع (signature)
عن طريق دمج العنوان، الحمولة، ومفتاح سري باستخدام الخوارزمية المحددة. يستخدم هذا التوقيع للتحقق من سلامة التوكن وضمان أنه لم يتم العبث به.
تستخدم JWTs بشكل شائع لأنها يمكن التحقق منها محليًا بواسطة العميل أو أي خدمة، دون الحاجة إلى التفاعل مع الخادم التفويضي. هذا يجعل JWTs فعّالة بشكل خاص لأنظمة الموزعة، حيث قد تحتاج خدمات متعددة إلى التحقق من صحة التوكن بشكل مستقل.
ومع ذلك، تأتي هذه السهولة مع مسؤولية ضمان عدم تعرض الclaims في التوكن بشكل مفرط، حيث تكون مرئية لأي شخص يمتلك التوكن. أيضًا، عادةً ما تكون JWTs صالحة لوقت قصير، ويتم تضمين وقت انتهاء الصلاحية في claims التوکن لضمان عدم صلاحية التوكن إلى الأبد.
التحقق من صلاحية توكن الوصول غير الشفاف
يتم التحقق من توکن الوصول غير الشفاف من خلال إعادته إلى الخادم التفويضي للتحقق. يحتفظ الخادم التفويضي بحالة التوكنات الصادرة ويمكنه تحديد صلاحية التوكن بناءً على تخزينه الداخلي.
- يطلب العميل توكن الوصول من الخادم التفويضي.
- يصدر الخادم التفويضي توكن غير شفاف.
- يرسل العميل طلب الوصول إلى المورد مع التوكن غير الشفاف في العنوان.
- يرسل مزود المورد طلب استقصاء التوكن ( RFC 7662: OAuth 2.0 Token Introspection ) إلى الخادم التفويضي للتحقق من صحة التوكن.
- يستجيب الخادم التفويضي بمعلومات التوكن.
التحقق من صحة توكن الوصول JWT (غير متصل)
يمكن التحقق من صحة توكن الوصول JWT دون اتصال من قبل العميل أو أي خدمة تمتلك الوصول إلى المفتاح العام للتوكن.
- يستبق مزود المورد المفتاح العام لخادم التفويض من نقطة الاكتشاف OIDC. يستخدم المفتاح العام للتحقق من توقيع التوكن وضمان سلامته.
- يطلب العميل توكن الوصول من الخادم التفويضي.
- يصدر الخادم التفويضي توكن JWT.
- يرسل العميل طلب الوصول إلى المورد مع توكن JWT في العنوان.
- يقوم مزود المورد بفك رمز توكن JWT والتحقق من صحته باستخدام المفتاح العام الذي تم الحصول عليه من الخادم التفويضي.
- يمنح مزود المورد الوصول بناءً على صلاحية التوكن.
حالات الاستخدام في OIDC
في سياق OIDC (اتصال OpenID)، تخدم التوكنات غير الشفافة وJWT أغراضًا مختلفة وتستخدم في سيناريوهات متميزة.
التوكنات غير الشفافة
- استرجاع ملف تعريف المستخدم:
افتراضيًا، عند طلب العميل توكن الوصول دون تحديد مورد ويدرج نطاق openid
، يصدر الخادم التفويضي توكن وصول غير شفاف. يُستخدم هذا التوكن أساسًا لاسترجاع معلومات ملف تعريف المستخدم من نقطة النهاية /oidc/userinfo
الخاصة بـ OIDC. عند تلقي الطلب بالتوكن غير الشفاف، يتحقق الخادم التفويضي من تخزينه الداخلي لاسترجاع المعلومات ذات الصلة بالتفويض والتحقق من صحة التوكن قبل الاستجابة بتفاصيل ملف تعريف المستخدم.
- تبادل التوكن المحدث:
تُصمم التوكنات المحدثة فقط للتبادل بين العميل والخادم التفويضي، دون الحاجة إلى مشاركتها مع مزودي الموارد. ونتيجة لذلك، تُصدر التوكنات المحدثة عادةً كتوكينات غير شفافة. عندما تنتهي صلاحية التوكن الوصول الحالي، يمكن للعميل استخدام التوكن المحدث غير الشفاف للحصول على توكن وصول جديد، مما يضمن الوصول المستمر دون إعادة مصادقة المستخدم.
توكنات JWT
- توكن المعرف (ID token):
في OIDC، توكن المعرف هو JWT يحتوي على معلومات المستخدم ويُستخدم لمصادقة المستخدم. يُصدر عادةً بجانب توكن الوصول، ويسمح توكن المعرف للعميل بالتحقق من هوية المستخدم. على سبيل المثال:
// الحمولة المفككة لتوكن المعرف
{
"iss": "<https://logto.io>",
"sub": "1234567890",
"aud": "client_id",
"exp": 1630368000,
"name": "John Doe",
"email": "[email protected]",
"picture": "<https://example.com/johndoe.jpg>"
}
يمكن للعميل التحقق من توكن المعرف لضمان هوية المستخدم واستخلاص معلومات المستخدم لأغراض التخصيص أو التفويض. توكن المعرف للاستخدام لمرة واحدة فقط ولا يجب استخدامه لتفويض موارد API.
- الوصول إلى موارد API (باستخدام توكن الوصول):
عندما يطلب العميل توكن الوصول بمؤشر مورد معين، يُصدر الخادم التفويضي توكن وصول JWT مخصص للوصول إلى ذلك المورد. يحتوي JWT على claims يمكن لمزود المورد استخدامها لتفويض وصول العميل. على سبيل المثال:
// الحمولة المفككة لتوكن الوصول JWT
{
"iss": "<https://dev.logto.app>",
"sub": "1234567890",
"aud": "<https://api.example.com>",
"scope": "read write",
"exp": 1630368000
}
يمكن لمزود المورد التحقق من الطلب من خلال التحقق من الclaims:
iss
: يؤكد أن التوكن صدر من خادم تفويض موثوق.sub
: يحدد المستخدم المرتبط بالتوكن.aud
: يضمن أن التوكن مخصص للمورد المحدد.scope
: يتحقق من الأذونات الممنوحة للمستخدم.