بدلاً من عرض تسجيل الدخول كسلسلة شاشات، نمثل PKCE كآلة حالات أمنية: بدأ العميل، أنشأ verifier، أرسل challenge، تلقى code، ثم حاول استبداله. كل انتقال له شرط سابق ونتيجة مسموحة، وأي محاولة خارج الترتيب تتحول إلى رفض يمكن تفسيره. هذه زاوية مناسبة لمشاريع تخرج الأمن السيبراني لأنها تختبر invariant واضحاً من دون حسابات حقيقية. تحدد RFC 7636 آلية PKCE، وتشرح RFC 8252 اعتبارات OAuth للتطبيقات الأصلية.
تنفيذ الاشتقاق والتدفق
يحصل العميل على verifier وفق قواعد الصيغة في RFC، ثم ينشئ challenge بطريقة S256 المعيارية. في واجهة الاختبار أظهر القيم غير السرية وما إذا كانت مطابقة، لا تعرض verifier ضمن التقرير النهائي. يستقبل الخادم الطلب الأول ويحفظ challenge مع code، ثم يتحقق عند الاستبدال من أن verifier المرسل ينتج challenge نفسه. افصل هذه الوظيفة عن منطق العرض كي يمكن اختبارها منفردة. توثق المواصفة التفاصيل الدقيقة؛ لا تستبدلها بخوارزمية مختصرة من ابتكار المشروع، ولا تفترض أن مجرد إضافة حقل باسم code_challenge يعني تطبيق PKCE.
اجعل التدفق قابلاً للإيقاف بعد كل انتقال. يستطيع الطالب عندئذ تبديل verifier أو تغيير clientId قبل طلب الاستبدال ويلاحظ النتيجة. أضف export للأحداث على هيئة JSON بعد إزالة القيم الحساسة، مع نسخة إعدادات السيناريو. ينبغي أن يقرأ التقرير سبب الرفض ومرحلة وقوعه. من الأفضل أن تكون كل تجربة معزولة عن غيرها وأن يعاد ضبط الحالة قبل إعادة التشغيل؛ وإلا ربما يبدو replay ناجحاً بسبب بقاء code قديم من تشغيل سابق.
اكتب transition table يوضح الحالة الحالية، الحدث، guard، والحالة التالية. مثلاً لا يقبل token endpoint حدث redeem قبل إصدار code، ولا يقبل إعادة الاستبدال بعد انتقال الجلسة إلى consumed. اختبر invariant أن code مربوط بالـchallenge والجلسة وredirect المسجل، وأن إبطال جلسة لا يترك نسخة قابلة للاستخدام في ذاكرة أخرى.
نموذج الحالات والرسائل
يمكن أن يحتوي سجل الجلسة على sessionId اصطناعي، clientId تجريبي، challengeMethod، challenge، codeId، expiresAt، redirectUri محلي، وحالة الاستخدام. لا تخزن كلمة مرور. احتفظ بالـverifier في جهة العميل داخل ذاكرة العملية، بينما يحفظ الخادم challenge والربط بالـcode. يجب أن يكون code أحادي الاستخدام في النموذج، وأن يرتبط بالجلسة وredirect URI. لا تعتبر وجود verifier صحيحاً كافياً إن كان code من جلسة أخرى أو انتهت صلاحيته. اكتب قواعد القبول كجدول يحدد أي شرط يجب أن يمر وأي شرط يؤدي إلى رفض صريح.
تعرض آلة الحالات مسارات success وdenied وexpired وreplayed وmismatch. لا تجعل الخطأ رسالة عامة واحدة؛ وضح للمختبر سبب الحالة مع تجنب تسريب قيمة سرية. استخدم مولد عشوائية مناسباً للمثال إن كانت اللغة توفره، لكن صرح أن المحاكي لا يقيس جودة توليد secrets. اربط كل event بمعرف session اصطناعي كي يمكن إعادة trace للسيناريو. إذا كان هناك أكثر من تبويب أو مستخدم افتراضي، يجب منع خلط رموزهم في الذاكرة.
حالة تجريبية خطوة بخطوة
ينشئ العميل جلسة A مع verifier V، ويشتق challenge C، ويرسل طلب التفويض للمتصفح المحلي. يصدر الخادم code X مرتبطاً بـC وبـredirect محلي. عند إعادة X مع V، ينجح الاستبدال مرة واحدة. أعد السيناريو مع verifier V2: يجب رفض الطلب لأن اشتقاقه لا يساوي C. أعد X بعد نجاحه: يجب أن يرفض كرمز مستهلك. بعد ذلك جرّب code لجلسة B مع verifier من A؛ لا ينبغي أن ينجح الربط. هذه أمثلة اصطناعية توضح سلوك النموذج ولا تثبت سلامة موفر هوية.
أظهر timeline صغيراً: من أنشأ الحدث، ما الحقول العامة التي انتقلت، وما القرار عند الخادم. لا تكتب «تم منع اختراق»؛ ما حدث هو أن assertion اختباري لم يطابق القاعدة المتوقعة. يستطيع تقرير المشروع إرفاق جدول المدخل/المخرج ونسخة RFC التي اعتمدها، بالإضافة إلى وصف ما لم يحاكه النظام. احرص على ألا تظهر قيم verifier في screenshots أو ملفات fixtures المتاحة علناً.
اختبارات القبول والفشل
اختبر نجاحاً واحداً، verifier غير مطابق، challenge method غير مدعوم، redirect مختلفاً، code منتهي الصلاحية، code مستخدماً سابقاً، وجلسة غير معروفة. أضف تحققاً من عدم ظهور verifier في السجل المصدر. يجب أن تكون النتيجة المتوقعة مستقلة عن ترتيب تشغيل الاختبارات؛ ابدأ كل حالة بمخزن نظيف أو معرفات جديدة. اختبر مدخلات ناقصة وقيم ذات طول خارج المدى، وتأكد أن الواجهة لا تعلق أو تتجاهل الخطأ. التغطية المهمة هنا ليست عدد السطور بل وجود حالة سلبية لكل قاعدة أمنية معلنة.
خط الأساس مقارنة تعليمية مع تدفق code مبسط لا يتحقق من verifier، وتستخدم فقط لبيان الفرق داخل المختبر. سجل السيناريوهات التي قبلها كل تنفيذ، ولا تعرض ذلك كمقياس حماية حقيقي. نفذ اختباراً يثبت أن code المستخدم مرتين يرفض في كليهما التنفيذ الثاني حتى عند verifier صحيح. وإذا فشل اختبار، افصل بين خطأ صياغة الرسالة وخطأ القاعدة. وثق إصدار المكتبة التشفيرية إن استعملتها، ولا تنشئ خوارزمية تشفير خاصة.
في threat model، افترض أن code قد يراه تطبيق آخر على الجهاز، لكن لا تفترض أن المهاجم يملك verifier الذي بقي لدى العميل الأصلي. أضف سيناريو اعتراض code ثم محاولة redeem بقيمة خاطئة. لا تحاكِ سرقة ذاكرة الجهاز أو اختراق المتصفح على أنها حالة يغطيها PKCE؛ أدرجها كخطر خارج نطاق هذه الآلية.
ارسم حدود التجربة
ابدأ بأربعة أطراف افتراضية: تطبيق عميل، متصفح، خادم تفويض محلي، ومبدل token. لا تنفذ صفحة دخول فعلية؛ استخدم مستخدماً وهمياً معروفاً وتسجيل أحداث واضحاً. الهدف اختبار ترابط الطلبات، لا كسر نظام. اكتب تدفقاً أساسياً: إنشاء verifier، اشتقاق challenge، بدء authorization request، إصدار code قصير العمر، ثم طلب الاستبدال. سجل كل انتقال ونتيجته وسبب الرفض. لا تضع أسراراً فعلية في logs ولا تسمح بإرسال عنوان callback إلى نطاق غير محلي. هذه القيود تجعل المشروع قابلاً للعرض من دون تعريض حساب أو خدمة خارجية للخطر.
تفرق واجهة المختبر بين بيانات عامة في الطلب وبين verifier الذي يجب أن يبقى لدى العميل. خزّن verifier داخل جلسة محاكاة قصيرة، وامسحه عند انتهائها. إذا أردت عرض القيمة للمناقشة، اعرض بصمة أو حالة مطابقة بدلاً من تسجيلها كاملة. عرّف ما لا يغطيه النموذج: لا يعالج تصيد صفحة الدخول، ولا صحة TLS في تطبيق حقيقي، ولا سياسات كل مزود. توثيق هذه الحدود يمنع تفسير النجاح المحلي كاعتماد أمني شامل.
نطاق التسليم وحدوده
تتكون النسخة المقترحة من واجهة خطوات، محرك حالات، مجموعة سيناريوهات، واختبارات آلية. يمكن تطويرها ضمن مشاريع التخرج ومناقشتها في مسار المشاريع البرمجية. وضح في العرض أن RFC 8252 تعالج اعتبارات تطبيقات native وتفضيل متصفح خارجي، بينما هذا المنتج يحاكي الرسائل ولا يوفر تسجيل دخول. لا تستخدم بيانات طلاب أو حسابات سحابية فعلية، ولا تضع endpoint عاماً يقبل callbacks من الإنترنت.
المحاكي لا يقيس متانة نظام كامل ولا يغطي إدارة الجلسة أو MFA أو حماية الجهاز أو ثغرات المتصفح. نتيجة قبول الحالات تعني أن الشيفرة اجتازت fixtures التي كتبتها فقط. اكتب فقرة صريحة عما يحتاجه تقييم مستقل عند الانتقال إلى تنفيذ حقيقي. بذلك يعرض مشروع التخرج فكرة مفيدة قابلة للتجربة، مع حدود لا تخفيها واجهة خضراء أو لغة مبالغ فيها.
المصادر
مراجعة المصادر: .
اختبار المثال وحدوده
أحداث اصطناعية لمزود محلي؛ لا يتصل المحاكي بمزود هوية أو مستخدمين حقيقيين.
مقالات ذات صلة
الخدمة المرتبطة: تطوير المشاريع البرمجية الجامعية.
أرسل متطلبات مشروعك