إنشاء مفتاح مرور لتسجيل الدخول بدون كلمة مرور

تجعل مفاتيح المرور حسابات المستخدمين أكثر أمانًا وبساطة وسهولة في الاستخدام.

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

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

آلية العمل

يمكن أن يُطلب من المستخدم إنشاء مفتاح مرور في إحدى الحالتَين التاليتَين:

  • عندما يسجّل مستخدم الدخول باستخدام كلمة مرور
  • عندما يسجّل مستخدم الدخول باستخدام مفتاح مرور من جهاز آخر (أي أنّ authenticatorAttachment هو cross-platform).
  • في صفحة مخصّصة يمكن للمستخدمين من خلالها إدارة مفاتيح المرور

لإنشاء مفتاح مرور، يمكنك استخدام WebAuthn API.

تتألف خطوات تسجيل مفتاح المرور من أربعة مكوّنات:

  • الخلفية: خادم الخلفية الذي يحتوي على قاعدة بيانات الحسابات التي تخزِّن المفتاح العام والبيانات الوصفية الأخرى عن مفتاح المرور
  • الواجهة الأمامية: الواجهة الأمامية التي تتواصل مع المتصفّح وتُرسِل requests for fetch (طلبات استرجاع البيانات) إلى الواجهة الخلفية
  • المتصفّح: متصفّح المستخدم الذي يشغّل JavaScript
  • Authenticator: أداة مصادقة المستخدم التي تنشئ ملف تعريف البريد الإلكتروني وتخزِّنه قد يشمل ذلك مدير كلمات المرور على الجهاز نفسه الذي يعمل عليه المتصفح (على سبيل المثال، عند استخدام Windows Hello) أو على جهاز آخر، مثل الهاتف.
مخطّط تسجيل مفتاح المرور

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

  1. سجَّل مستخدم الدخول إلى الموقع الإلكتروني.
  2. بعد تسجيل دخول المستخدم، يطلب إنشاء مفتاح مرور على واجهة المستخدم، على سبيل المثال، من خلال الضغط على زر "إنشاء مفتاح مرور".
  3. تطلب الواجهة الأمامية معلومات من الخلفي لإنشاء مفتاح مرور، مثل معلومات العميل وتحدّي وأرقام تعريف بيانات الاعتماد المطلوب استبعادها.
  4. يتصل الواجهة الأمامية بخدمة navigator.credentials.create() لإنشاء مفتاح مرور. تُعرِض هذه الدعوة وعدًا.
  5. يتم إنشاء مفتاح مرور بعد موافقة المستخدم باستخدام قفل شاشة الجهاز. يتم حلّ الوعد ويتم عرض بيانات اعتماد المفتاح العام في الواجهة الأمامية.
  6. تُرسِل الواجهة الأمامية بيانات اعتماد المفتاح العام إلى الواجهة الخلفية وتخزِّن معرّف بيانات الاعتماد والمفتاح العام المرتبط بحساب المستخدم لعمليات مصادقة المستقبلية.

التوافق

تتوافق معظم المتصفحات مع WebAuthn، ولكن هناك بعض الثغرات الصغيرة. يُرجى الرجوع إلى التوافق مع الأجهزة - passkeys.dev لمعرفة مجموعات المتصفحات وأنظمة التشغيل التي تتيح إنشاء مفتاح مرور.

إنشاء مفتاح مرور جديد

في ما يلي كيفية عمل الواجهة الأمامية عند تلقّي طلب لإنشاء مفتاح مرور جديد.

رصد الميزات

قبل عرض زر "إنشاء مفتاح مرور جديد"، تحقَّق مما يلي:

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

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

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

المصدر

  • يتيح الجهاز مصادقة المنصة (يمكنه إنشاء مفتاح مرور و المصادقة باستخدام مفتاح المرور) باستخدام PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable().

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

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

المصدر

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

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

المصدر

// Availability of `window.PublicKeyCredential` means WebAuthn is usable.  
// `isUserVerifyingPlatformAuthenticatorAvailable` means the feature detection is usable.  
// `​​isConditionalMediationAvailable` means the feature detection is usable.  
if (window.PublicKeyCredential &&  
   
PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable &&  
   
PublicKeyCredential.​​isConditionalMediationAvailable) {  
 
// Check if user verifying platform authenticator is available.  
 
Promise.all([  
   
PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable(),  
   
PublicKeyCredential.​​isConditionalMediationAvailable(),  
 
]).then(results => {  
   
if (results.every(r => r === true)) {  
     
// Display "Create a new passkey" button  
   
}  
 
});  
}  

لن تتوفّر مفاتيح المرور في هذا المتصفّح إلى أن يتم استيفاء جميع الشروط. من المفترض ألا يظهر الزر "إنشاء مفتاح مرور جديد" إلى ذلك الحين.

جلب معلومات مهمة من الخلفية

عندما ينقر المستخدم على الزر، يمكنك جلب معلومات مهمة للاتصال navigator.credentials.create() من الخلفية:

  • challenge: تحدّي ينشئه الخادم في ArrayBuffer لهذا التسجيل. هذا الإجراء مطلوب، ولكن لا يتم استخدامه أثناء التسجيل ما لم يتم إجراء شهادة إثبات، وهوموضوع متقدّم لا يتم تناوله هنا.
  • user.id: معرّف فريد للمستخدم. يجب أن تكون هذه القيمة ArrayBuffer لا تتضمّن معلومات تحدّد الهوية الشخصية، مثل عناوين البريد الإلكتروني أو أسماء المستخدمين. ستعمل بشكل جيد قيمة عشوائية تبلغ 16 بايت يتم إنشاؤها لكل حساب.
  • user.name: يجب أن يحتوي هذا الحقل على معرّف فريد للحساب يمكن للمستخدم التعرّف عليه، مثل عنوان بريده الإلكتروني أو اسمه المستخدِم. سيتم عرض هذا في أداة اختيار الحسابات. (في حال استخدام اسم مستخدم، استخدِم القيمة نفسها المستخدَمة في مصادقة كلمة المرور).
  • user.displayName: هذا الحقل هو اسم مطلوب للحساب وأكثر ملاءمةً للمستخدم. ولا يلزم أن يكون فريدًا، ويمكن أن يكون الاسم الذي يختاره المستخدم. إذا لم يكن لموقعك الإلكتروني قيمة مناسبة لإدراجها هنا، أرسِل سلسلة فارغة. قد يظهر ذلك في أداة اختيار الحساب حسب المتصفّح.
  • excludeCredentials: يمنع تسجيل الجهاز نفسه من خلال تقديم قائمة بأرقام تعريف مستندات الاعتماد التي سبق تسجيلها. يجب أن يحتوي العنصر transports member، في حال توفّره، على نتيجة استدعاء العنصر getTransports() أثناء تسجيل كل بيانات اعتماد.

طلب WebAuthn API لإنشاء مفتاح مرور

يُرجى الاتصال على navigator.credentials.create() لإنشاء مفتاح مرور جديد. تُعرِض واجهة برمجة التطبيقات وعدًا بالانتظار إلى أن يتفاعل المستخدم مع مربّع حوار مشروط.

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

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

المصدر

const publicKeyCredentialCreationOptions = {
  challenge
: *****,
  rp
: {
    name
: "Example",
    id
: "example.com",
 
},
  user
: {
    id
: *****,
    name
: "john78",
    displayName
: "John",
 
},
  pubKeyCredParams
: [{alg: -7, type: "public-key"},{alg: -257, type: "public-key"}],
  excludeCredentials
: [{
    id
: *****,
    type
: 'public-key',
    transports
: ['internal'],
 
}],
  authenticatorSelection
: {
    authenticatorAttachment
: "platform",
    requireResidentKey
: true,
 
}
};

const credential = await navigator.credentials.create({
  publicKey
: publicKeyCredentialCreationOptions
});

// Encode and send the credential to the server for verification.  

في ما يلي المَعلمات التي لم يتم شرحها أعلاه:

  • rp.id: معرّف مقدّم الخدمة هو نطاق ويمكن لموقع إلكتروني تحديد نطاقه أو لاحقة قابلة للتسجيل. على سبيل المثال، إذا كان مصدر نقطة الانطلاق هو https://login.example.com:1337، يمكن أن يكون رقم تعريف نقطة الانطلاق هو login.example.com أو example.com. إذا تم تحديد معرّف مقدّم الخدمة على النحو التالي: example.com، يمكن للمستخدم المصادقة على login.example.com أو على أي نطاقات فرعية على example.com.

  • rp.name: اسم الجهة المحظورة

  • pubKeyCredParams: يحدِّد هذا الحقل خوارزميات المفاتيح العامة المتوافقة مع موفِّر خدمات الربط. ننصح بضبطه على [{alg: -7, type: "public-key"},{alg: -257, type: "public-key"}]. يحدِّد هذا الإجراء مدى توفُّر ECDSA مع P-256 وRSA PKCS#1 ، ويمنح توفُّر هذه العناصر تغطية كاملة.

  • authenticatorSelection.authenticatorAttachment: اضبط هذا الخيار على "platform" إذا كان إنشاء مفتاح المرور هذا ترقية من كلمة مرور، مثلاً في عرض ترويجي بعد تسجيل الدخول. يشير الرمز "platform" إلى أنّ العميل يريد مصادقة نظام أساسي (مصادقة مضمّنة في جهاز النظام الأساسي) لن تطلب منه إدخال مفتاح أمان USB مثلاً. يتوفر للمستخدم خيار أبسط لإنشاء مفتاح مرور.

  • authenticatorSelection.requireResidentKey: اضبطها على قيمة منطقية "true". تخزِّن بيانات الاعتماد القابلة للاكتشاف (مفتاح الإقامة) معلومات المستخدم في مفتاح المرور وتسمح للمستخدمين باختيار الحساب عند المصادقة. اطّلِع على مزيد من المعلومات عن بيانات الاعتماد القابلة للاكتشاف في مقالة نظرة تفصيلية على بيانات الاعتماد القابلة للاكتشاف.

  • authenticatorSelection.userVerification: يشير إلى ما إذا كان إثبات هوية المستخدم باستخدام قفل شاشة الجهاز هو "required" أو "preferred" أو "discouraged". القيمة التلقائية هي "preferred"، ما يعني أنّ معتمِد الهوية قد يتخطّى عملية إثبات هوية المستخدم. اضبط هذا الخيار على "preferred" أو فاتِح السمة.

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

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

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

  • InvalidStateError: سبق أن تم إنشاء مفتاح مرور على الجهاز. لن يظهر للمستخدم مربّع حوار بشأن خطأ، ويجب ألا يتعامل الموقع الإلكتروني مع ذلك على أنّه خطأ، لأنّ المستخدم أراد تسجيل الجهاز المحلي وتم تسجيله.
  • NotAllowedError: ألغى المستخدم العملية.
  • الاستثناءات الأخرى: حدث خطأ غير متوقّع. يعرض المتصفّح مربّع حوار خطأ للمستخدم.

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

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

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

حفظ بيانات الاعتماد

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

يمكنك بعد ذلك تخزين المعلومات التي تم استرجاعها من بيانات الاعتماد في قاعدة البيانات لاستخدامها في المستقبل. تتضمّن القائمة التالية بعض السمات النموذجية التي يجب حفظها:

  • رقم تعريف بيانات الاعتماد (المفتاح الأساسي)
  • رقم تعريف المستخدم
  • المفتاح العام

تتضمّن بيانات اعتماد المفتاح العام أيضًا المعلومات التالية التي قد تحتاج إلى حفظها في قاعدة البيانات:

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

لمصادقة المستخدم، يُرجى الاطّلاع على مقالة تسجيل الدخول باستخدام مفتاح مرور من خلال ميزة preenchimento automático (الملء التلقائي) للنموذج.

الموارد