إضافة طريقة مصادقة جديدة "مُدارة" إلى Discourse

بالاستمرار من Future Social Authentication Improvements

نحن الآن بصدد نقل جميع معلومات “الحساب المرتبط” إلى جدول قاعدة بيانات واحد. سيساعد هذا في تقليل المنطق المكرر بشكل كبير، والسماح بتطوير أسرع في المستقبل. على سبيل المثال، أدى ترحيل منطق تويتر الأساسي لدينا إلى النظام الجديد إلى تقليل عدد أسطر التعليمات البرمجية من 136 إلى 24 فقط :tada:.

هذا المنشور ليس مصممًا ليكون دليل تعليمات خطوة بخطوة لإضافة موفر مصادقة جديد، ولكنه سيهدف إلى تقديم نظرة عامة، مع الإشارة إلى التعليمات البرمجية المصدر ذات الصلة عند الضرورة.

تنفيذ الموثِّق (Authenticator)

يجب على كل موثِّق تنفيذ فئة فرعية من Auth::Authenticator. لاستخدام المنطق المشترك الجديد، يمكن للموثِّق بدلاً من ذلك أن يرث من Auth::ManagedAuthenticator. يمكن العثور على مثال للتنفيذ الأساسي في موثِّق فيسبوك الأساسي:

يجب على الفئات المنفِّذة تجاوز name و enabled? و register_middleware.

:information_source: على الهامش: للتوافق مع مواقع متعددة (multisite)، من المهم توفير أي معلومات خاصة بالموقع إلى omniauth في دالة لامدا setup، بدلاً من أن تكون ثابتة وقت التعريف. شاهد جميع الموثِّقات الأساسية للحصول على أمثلة لذلك.

تتم معالجة جميع المنطق لربط الحسابات الخارجية بحسابات Discourse بواسطة Auth::ManagedAuthenticator. يعتمد هذا على أن يعيد موفِّر omniauth البيانات بالتنسيق المحدد في توثيقهم. إذا كانت هناك حاجة إلى أي معالجة لهذه البيانات، يمكن للموثِّقات تجاوز التابع after_authenticate، ومعالجة الرمز المميز للمصادقة (auth_token) حسب الحاجة. على سبيل المثال، يزيل موثِّق تويتر الأساسي جميع معلومات extra من الرمز المميز:

يتم تخزين البيانات في جدول قاعدة البيانات user_associated_accounts. يتم أخذ provider_uid و info و credentials و extra مباشرة من البيانات المُعادة من omniauth.

بمجرد تعريف فئة Authenticator، يجب تسجيلها. يجب أن يحدث هذا مبكرًا في دورة حياة التطبيق، ولا يمكن أن يحدث داخل طريقة after_initialize الخاصة بالإضافة (plugin). يمكن أن يحتوي الحد الأدنى من التسجيل على مرجع إلى الموثِّق. في الإضافة، يمكن إجراء التسجيل باستخدام الدالة auth_provider. على سبيل المثال:

auth_provider authenticator: OpenIDConnectAuthenticator.new()

في الكود الأساسي، يتم التسجيل في discourse.rb. يمكن العثور على قائمة كاملة بالخيارات الممكنة لـ AuthProvider هنا. يمكن تعريف محتوى نصي باستخدام هذه الخيارات، ولكن من الأفضل توفير سلاسل نصية قابلة للترجمة في client.en.yml باتباع المفاتيح القياسية. على سبيل المثال:

ملاحظات إضافية حول ManagedAuthenticator بواسطة @fantasticfears

ManagedAuthenticator بالتفصيل

قد تحتاج إلى العمل على شيء خاص للمصادقة. وقد ترغب في معرفة المزيد عن ManagedAuthenticator. في الأساس، لديه العديد من العمليات والخيارات، ويتحكم في كيفية استخدام البيانات.

تدير Discourse معلومات المستخدم باستخدام وحدتي تحكم (controllers). تدير Users::OmniauthCallbacksController الحمولة (payload) بمجرد اكتمال مصادقة OAuth2. يتم استدعاء after_authenticate هنا. يتم استخدام can_connect_existing_user? هنا أيضًا.
هناك بعض التوابع الخاصة التي يمكنك قراءتها لفهم كيفية عمل حقول البيانات المختلفة.

if authenticator.can_connect_existing_user? && current_user
  @auth_result = authenticator.after_authenticate(auth, existing_account: current_user)
else
  @auth_result = authenticator.after_authenticate(auth)
end

تحتوي UsersController على revoke_account الذي يستخدم can_revoke? و revoke. ولكن لكي يعمل التابع revoke عن بُعد، تحتاج إلى بناء التنفيذ الخاص بك.

UserAuthenticator هو فئة خدمة تساعد في مصادقة المستخدمين (التحقق من تأكيد البريد الإلكتروني أو مسار OAuth2). يتم استدعاء after_create_account هنا.

يبقى المنطق الأساسي في after_authenticate مع فئة بيانات Auth::Result. نتبع هيكل البيانات هنا. سيتم تمرير extra_data إلى after_create_account لإنشاء السجلات ذات الصلة.

result.extra_data = {
  provider: auth_token[:provider],
  uid: auth_token[:uid],
  info: auth_token[:info],
  extra: auth_token[:extra],
  credentials: auth_token[:credentials]
}

سيحاول مطابقة وتوصيل حساب موجود.
قد تتساءل لماذا إنشاء الحساب التلقائي ممكن ولكن لا يوجد User.create. يتم ذلك في UsersController#create.

authentication = UserAuthenticator.new(user, session)

المستخدم عبارة عن مثيل جديد سيتم ملؤه ببيانات الجلسة التي يتم إعدادها بواسطة موفر المصادقة. ثق بي، إنه مجرد سحر.


الترحيل إلى النظام الجديد

لتوفير تحويل سلس إلى النظام الجديد، يجب ترحيل البيانات من موقع التخزين القديم. بالنسبة لموفِّري المصادقة الأساسيين، قد تكون هذه جداول مخصصة. بالنسبة للإضافات، قد تكون هذه صفوف plugin_store_rows، أو oauth2_user_infos. الحد الأدنى من البيانات المطلوبة في صف user_associated_accounts هو provider_name و provider_uid و user_id. للحصول على مثال للترحيل، انظر:

بمجرد إصدار نظام ManagedAuthenticator إلى الفرع المستقر بالإصدار 2.2.0، سنبدأ في ترحيل الإضافات الرسمية للمصادقة. عند هذه النقطة، سيتم إضافة مثال ترحيل لـ plugin_store_row هنا.


يتم التحكم في إصدار هذا المستند - اقترح التغييرات على github.

23 إعجابًا

@david كل العمل المنجز هنا رائع للغاية. أقدر ذلك كثيراً. أتيحت لي أيضاً فرصة اللعب بـ GitHub - discourse/discourse-development-auth: A discourse plugin which adds a fake authentication provider. For development purposes only. وهو مفيد للغاية.

مجرد تحذير واحد، الميزة لا تعمل بشكل جيد (لا تظهر نافذة التسجيل المنبثقة) مع ember cli محلياً. كنت أحك رأسي أثناء كتابة إضافة لمزود مصادقة وفجأة خطر ببالي استخدام NO_EMBER_CLI=1 وبدأت كل الأمور تعمل.

7 إعجابات

أود أن أعرف ما إذا كان تطبيق المصادق سيكون المسار الصحيح نحو

هل أفهم بشكل صحيح أن جميع المصادقات المسجلة يتم استدعاؤها في وقت مبكر من التطبيق، لذلك يمكنني الاختبار هناك، إذا تم تضمين اسم مستخدم وبعض التلميحات للمصادقة عبر البريد الإلكتروني في عنوان URL وعرض نموذج “إرسال رابط تسجيل دخول لي” كرد؟