تسجيل الدخول باستخدام مفتاح مرور من خلال الملء التلقائي للنموذج

أنشئ تجربة تسجيل دخول تستفيد من مفاتيح المرور مع مواصلة استيعاب مستخدمي كلمات المرور الحالية.

تحلّ مفاتيح المرور محل كلمات المرور، وتجعل حسابات المستخدمين على الويب أكثر أمانًا وبساطة وسهولة في الاستخدام. ومع ذلك، يمكن أن يؤدي الانتقال من المصادقة المستندة إلى كلمة المرور إلى المصادقة المستندة إلى مفتاح المرور إلى تعقيد تجربة المستخدم. يمكن أن يساعد استخدام ميزة "الملء التلقائي" للنموذج في اقتراح مفاتيح المرور في إنشاء تجربة موحدة.

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

من الناحية المثالية، لن يكون هناك مستخدمون لكلمات المرور، ويمكن أن تكون عملية المصادقة بسيطة مثل زر تسجيل دخول واحد. عندما ينقر المستخدم على الزر، ينبثق مربع حوار محدد حساب، ويمكن للمستخدم اختيار حساب وفتح قفل الشاشة للتحقّق من الحساب وتسجيل الدخول.

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

مفاتيح المرور هي أيضًا تقنية جديدة. وقد يشكّل شرحها والتأكّد من شعور المستخدمين بالراحة عند استخدامها تحديًا للمواقع الإلكترونية. يمكننا الاعتماد على تجارب مألوفة للمستخدمين في ملء كلمات المرور تلقائيًا لحلّ كلتا المشكلتَين.

واجهة مستخدِم مشروطة

لتوفير تجربة مستخدم فعّالة لكل من مستخدمي مفاتيح المرور وكلمات المرور، يمكنك تضمين مفاتيح المرور في اقتراحات الملء التلقائي. يُعرف هذا باسم واجهة مستخدم شَرطية وهو جزء من معيار WebAuthn.

بعد أن ينقر المستخدم على حقل إدخال اسم المستخدم، ينبثق مربّع حوار يعرض اقتراحات للملء التلقائي تُبرز مفاتيح المرور المخزّنة مع اقتراحات للملء التلقائي لكلمة المرور. يمكن للمستخدم بعد ذلك اختيار حساب واستخدام قفل شاشة الجهاز لتسجيل الدخول.

بهذه الطريقة، يمكن للمستخدمين تسجيل الدخول إلى موقعك الإلكتروني باستخدام النموذج الحالي كما لو لم يكن هناك أي تغيير، ولكن مع ميزة الأمان الإضافية التي يوفّرها مفاتيح المرور إذا كان لديهم مفتاح.

آلية العمل

لمصادقة المستخدم باستخدام مفتاح مرور، يمكنك استخدام سمة WebAuthn API.

المكونات الأربعة في مسار مصادقة مفتاح المرور هي: المستخدم:

  • الخلفية: خادم الخلفية الذي يحتوي على قاعدة بيانات الحسابات التي تخزِّن المفتاح العام والبيانات الوصفية الأخرى عن مفتاح المرور
  • الواجهة الأمامية: هي الواجهة التي تتواصل مع المتصفّح وترسل طلبات الاسترداد إلى الواجهة الخلفية.
  • المتصفّح: متصفّح المستخدم الذي يشغّل JavaScript
  • Authenticator: أداة مصادقة المستخدم التي تنشئ مفتاح المرور وتخزّنه قد يكون ذلك على الجهاز نفسه الذي يعمل عليه المتصفّح (مثلاً عند استخدام Windows Hello) أو على جهاز آخر، مثل الهاتف.
مخطّط مصادقة مفتاح المرور
  1. بعد وصول المستخدم إلى الواجهة الأمامية، تطلب الواجهة من الخلفية طلب مصادقة باستخدام مفتاح مرور، وتستدعي navigator.credentials.get() لبدء المصادقة باستخدام مفتاح مرور. يؤدي ذلك إلى عرض Promise.
  2. عندما يضع المستخدم المؤشر في حقل تسجيل الدخول، يعرض المتصفّح مربّع حوار لملء كلمة المرور تلقائيًا، بما في ذلك مفاتيح المرور. يظهر مربّع حوار مصادقة إذا اختار المستخدم مفتاح مرور.
  3. بعد أن يُثبت المستخدم هويته باستخدام قفل شاشة الجهاز، يتم حلّ promise ويتم عرض بيانات اعتماد المفتاح العام في الواجهة الأمامية.
  4. تُرسِل الواجهة الأمامية بيانات اعتماد المفتاح العام إلى الواجهة الخلفية. تحقّق الخلفية من التوقيع مقارنةً بالمفتاح العام للحساب المطابق في قاعدة البيانات. وفي حال نجاح العملية، يتم تسجيل دخول المستخدم.

المصادقة باستخدام مفتاح مرور من خلال الملء التلقائي للنموذج

عندما يريد المستخدم تسجيل الدخول، يمكنك إجراء طلب WebAuthn get مشروط للإشارة إلى أنّه قد يتم تضمين مفاتيح المرور في اقتراحات الملء التلقائي. لا يؤدي الطلب المشروط إلى واجهة برمجة التطبيقات navigator.credentials.get() في WebAuthn إلى عرض واجهة المستخدم ويظل في انتظار المراجعة إلى أن يختار المستخدم حسابًا لتسجيل الدخول باستخدامه من اقتراحات الملء التلقائي. إذا اختار المستخدم مفتاح مرور، سيحلّ المتصفّح الوعد باستخدام بيانات اعتماد بدلاً من ملء نموذج تسجيل الدخول. بعد ذلك، تقع على عاتق الصفحة مسؤولية تسجيل دخول المستخدم.

إضافة تعليق توضيحي إلى حقل إدخال النموذج

أضِف سمة autocomplete إلى حقل اسم المستخدم input، إذا لزم الأمر. أضِف username وwebauthn كعنصرَين تعريفيَّين للسماح للتطبيق باقتراح مفاتيح المرور.

<input type="text" name="username" autocomplete="username webauthn" ...>

رصد الميزات

قبل استدعاء طلب مشروط لواجهة برمجة التطبيقات WebAuthn، تحقَّق مما يلي:

  • يتوافق المتصفّح مع WebAuthn باستخدام PublicKeyCredential.

توافق المتصفّح

  • Chrome: 67
  • Edge: 18.
  • Firefox: 60
  • Safari: 13

المصدر

توافق المتصفّح

  • Chrome: 108
  • الحافة: 108.
  • Firefox: 119.
  • ‫Safari: 16

المصدر

// Availability of `window.PublicKeyCredential` means WebAuthn is usable.  
if (window.PublicKeyCredential &&  
   
PublicKeyCredential.​​isConditionalMediationAvailable) {  
 
// Check if conditional mediation is available.  
 
const isCMA = await PublicKeyCredential.​​isConditionalMediationAvailable();  
 
if (isCMA) {  
   
// Call WebAuthn authentication  
 
}  
}  

جلب طلب مصادقة من خادم موفِّر الهوية

استرجاع طلب تأكيد هوية من خادم RP المطلوب للاتصال navigator.credentials.get():

  • challenge: تحدّي ينشئه الخادم في ArrayBuffer. هذا الإجراء مطلوب لمنع هجمات إعادة التشغيل. احرص على إنشاء طلب تأكيد جديد في كل محاولة تسجيل دخول وتجاهله بعد فترة معيّنة أو بعد تعذُّر إثبات صحة محاولة تسجيل الدخول. يمكنك اعتباره مثل رمز CSRF.
  • allowCredentials: مصفوفة من بيانات الاعتماد المقبولة لمصادقة هذا النوع. نقْل صفيف خالٍ للسماح للمستخدم باختيار مفتاح مرور متاح من قائمة يعرضها المتصفّح.
  • userVerification: يشير إلى ما إذا كان إثبات هوية المستخدم باستخدام قفل شاشة الجهاز هو "required" أو "preferred" أو "discouraged". القيمة التلقائية هي "preferred"، ما يعني أنّ معتمِد الهوية قد يتخطّى عملية إثبات هوية المستخدم. اضبط هذا الخيار على "preferred" أو فاتِح السمة.

استدعاء WebAuthn API باستخدام العلامة conditional لمصادقة المستخدم

اتصل بالرقم navigator.credentials.get() لبدء انتظار مصادقة المستخدم.

// To abort a WebAuthn call, instantiate an `AbortController`.
const abortController = new AbortController();

const publicKeyCredentialRequestOptions = {
 
// Server generated challenge
  challenge
: ****,
 
// The same RP ID as used during registration
  rpId
: 'example.com',
};

const credential = await navigator.credentials.get({
  publicKey
: publicKeyCredentialRequestOptions,
  signal
: abortController.signal,
 
// Specify 'conditional' to activate conditional UI
  mediation
: 'conditional'
});
  • rpId: معرّف مقدّم الخدمة هو نطاق ويمكن لموقع إلكتروني تحديد نطاقه أو لاحقة قابلة للتسجيل. يجب أن تتطابق هذه القيمة مع rp.id المستخدَم عند إنشاء مفتاح المرور.

تذكَّر تحديد mediation: 'conditional' لجعل الطلب مشروطًا.

إرسال بيانات اعتماد المفتاح العام المعروضة إلى خادم نقطة المراجعة

بعد أن يختار المستخدم حسابًا ويوافق عليه باستخدام قفل شاشة الجهاز، يتم حلّ الوعد من خلال عرض عنصر PublicKeyCredential في واجهة برمجة التطبيقات لوحدة التحكّم في الوصول.

يمكن رفض الوعد لعدة أسباب مختلفة. عليك معالجة الأخطاء وفقًا لذلك، استنادًا إلى سمة name لعنصر Error:

  • NotAllowedError: ألغى المستخدم العملية.
  • الاستثناءات الأخرى: حدث خطأ غير متوقّع. يعرض المتصفّح مربّع حوار خطأ للمستخدم.

يحتوي عنصر بيانات اعتماد المفتاح العام على السمات التالية:

  • id: رقم تعريف مشفّر بترميز base64url لمستند اعتماد مفتاح المرور الذي تم إثبات ملكيته.
  • rawId: إصدار ArrayBuffer من معرّف بيانات الاعتماد.
  • response.clientDataJSON: ArrayBuffer لبيانات العميل يحتوي هذا الحقل على معلومات مثل التحدّي والمصدر الذي يجب أن يُثبته خادم RP.
  • response.authenticatorData: ArrayBuffer لبيانات معتمِد المصادقة يحتوي هذا الحقل على معلومات مثل رقم تعريف RP.
  • response.signature: ArrayBuffer للتوقيع هذه القيمة هي جوهر بيانات الاعتماد ويجب إثبات صحتها على الخادم.
  • response.userHandle: ArrayBuffer التي تحتوي على رقم تعريف المستخدم الذي تم ضبطه في وقت الإنشاء يمكن استخدام هذه القيمة بدلاً من معرّف بيانات الاعتماد إذا كان الخادم بحاجة إلى اختيار قيم المعرّفات التي يستخدمها، أو إذا أرادت الخلفية تجنُّب إنشاء فهرس لمعرّفات بيانات الاعتماد.
  • authenticatorAttachment: يعرض القيمة platform عندما تكون بيانات الاعتماد هذه واردة من الجهاز المحلي. بخلاف ذلك، cross-platform، لا سيما عندما استخدم المستخدم هاتفًا لتسجيل الدخول. إذا كان المستخدم بحاجة إلى استخدام هاتف لتسجيل الدخول، ننصحك بمطالبته بإنشاء مفتاح مرور على الجهاز المحلي.
  • type: يتم ضبط هذا الحقل دائمًا على "public-key".

إذا كنت تستخدم مكتبة لمعالجة عنصر بيانات الاعتماد للمفتاح العام على خادم RP، ننصحك بإرسال العنصر بالكامل إلى الخادم بعد تشفيره جزئيًا باستخدام base64url.

التحقّق من التوقيع

عند استلام بيانات اعتماد المفتاح العام على الخادم، عليك تمريرها إلى مكتبة FIDO لمعالجة العنصر.

ابحث عن رقم تعريف بيانات الاعتماد المطابق باستخدام السمة id (إذا كنت بحاجة إلى تحديد حساب المستخدم، استخدِم السمة userHandle التي هي user.id التي حدّدتها عند إنشاء بيانات الاعتماد). اطّلِع على ما إذا كان يمكن التحقّق من صحة بيانات اعتماد العميل signature باستخدام المفتاح العام المخزّن. لإجراء ذلك، ننصحك باستخدام مكتبة أو حلّ من جهة الخادم بدلاً من كتابة الرمز البرمجي الخاص بك. يمكنك العثور على مكتبات مفتوحة المصدر في مستودع GitHub الخاص بـ awesome-webauth.

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

اتّبِع تعليمات أكثر تفصيلاً في مقالة مصادقة مفتاح المرور من جهة الخادم.

الموارد