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

متابعةً من Future Social Authentication Improvements

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

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

تنفيذ أداة مصادقة (Authenticator)

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

يجب تجاوز name و enabled? و register_middleware عن طريق الفئات المنفذة.

:information_source: ملاحظة جانبية: للتوافق مع مواقع متعددة، من المهم أن يتم توفير أي معلومات خاصة بالموقع إلى 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 معلومات المستخدم باستخدام وحدتي تحكم. تدير Users::OmniauthCallbacksController الحمولة بمجرد اكتمال مصادقة 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 إلى الفرع المستقر بالإصدار v2.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 وعرض نموذج “إرسال رابط تسجيل دخول لي” كرد؟