على الرغم من أنّ بيانات اعتماد FIDO، مثل مفاتيح المرور، تهدف إلى استبدال كلمات المرور، يمكن لمعظمها أيضًا تجنيب المستخدم عناء كتابة اسم مستخدم. يتيح ذلك للمستخدمين المصادقة من خلال اختيار حساب من قائمة مفاتيح المرور التي يملكونها للموقع الإلكتروني الحالي.
تم تصميم الإصدارات السابقة من مفاتيح الأمان كطرق مصادقة بخطوتين، وكانت تتطلّب أرقام تعريف بيانات الاعتماد المحتمَلة، وبالتالي تتطلّب إدخال اسم مستخدم. تُعرف بيانات الاعتماد التي يمكن لمفتاح الأمان العثور عليها بدون معرفة أرقام تعريفها باسم بيانات الاعتماد القابلة للاكتشاف. إنّ معظم بيانات اعتماد FIDO التي يتم إنشاؤها اليوم هي بيانات اعتماد قابلة للاكتشاف، لا سيما مفاتيح المرور المخزّنة في خدمة إدارة كلمات المرور أو على مفتاح أمان حديث.
لضمان إنشاء بيانات الاعتماد كمفاتيح مرور (بيانات اعتماد قابلة للاكتشاف)، حدِّد residentKey
وrequireResidentKey
عند إنشاء بيانات الاعتماد.
يمكن للأطراف المعتمَدة (RP) استخدام بيانات الاعتماد القابلة للاكتشاف من خلال حذف
allowCredentials
أثناء مصادقة مفتاح المرور. في هذه الحالات، يعرض المتصفّح أو النظام للمستخدم قائمة بكلمات المرور المتاحة، والتي يتم تحديدها من خلال سمة
user.name
التي تم ضبطها في وقت الإنشاء. إذا اختار المستخدم أحدهما، سيتم تضمين القيمة user.id
في التوقيع الناتج. يمكن للخادم بعد ذلك استخدام ذلك أو
رقم تعريف بيانات الاعتماد المعروض للبحث عن الحساب بدلاً من اسم مستخدم مكتوب.
لا تعرض واجهات مستخدم أداة اختيار الحسابات، مثل تلك التي ناقشناها سابقًا، أبدًا بيانات اعتماد غير قابلة للاكتشاف.
requireResidentKey
وresidentKey
لإنشاء مفتاح مرور، حدِّد authenticatorSelection.residentKey
وauthenticatorSelection.requireResidentKey
في navigator.credentials.create()
بالقيم الموضَّحة أدناه.
async function register () {
// ...
const publicKeyCredentialCreationOptions = {
// ...
authenticatorSelection: {
authenticatorAttachment: 'platform',
residentKey: 'required',
requireResidentKey: true,
}
};
const credential = await navigator.credentials.create({
publicKey: publicKeyCredentialCreationOptions
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
residentKey
:
'required'
: يجب إنشاء بيانات اعتماد قابلة للاكتشاف. وإذا تعذّر إنشاؤه، يتم عرضNotSupportedError
.'preferred'
: يفضّل مقدّم الطلبات إنشاء بيانات اعتماد قابلة للاكتشاف، ولكنه يقبل بيانات اعتماد غير قابلة للاكتشاف.'discouraged'
: تفضّل الجهة المحظورة إنشاء بيانات اعتماد غير قابلة للاكتشاف، ولكنها تقبل بيانات اعتماد قابلة للاكتشاف.
requireResidentKey
:
- يتم الاحتفاظ بهذه السمة لضمان التوافق مع الإصدارات القديمة من WebAuthn Level 1، وهو إصدار قديم من المواصفة. اضبط هذا الخيار على
true
إذا كانت قيمةresidentKey
هي'required'
، وإلا اضبطه علىfalse
.
allowCredentials
يمكن لموفّري الخدمات الوكيلين استخدام allowCredentials
على navigator.credentials.get()
للتحكّم في تجربة مصادقة مفتاح المرور. هناك عادةً ثلاثة أنواع من تجارب مصادقة مفتاح المرور:
عرض أداة اختيار حساب في نافذة منبثقة
باستخدام بيانات الاعتماد القابلة للاكتشاف، يمكن لخدمات الربط بالخدمات عرض أداة اختيار حساب مشروطة للمستخدم لاختيار حساب لتسجيل الدخول باستخدامه، ثم إكمال عملية إثبات هوية المستخدم. هذا مناسب لمسار مصادقة مفتاح المرور الذي يتم بدؤه بالضغط على زر مخصّص لمصادقة مفتاح المرور.
لتحقيق تجربة المستخدم هذه، عليك حذف صفيف فارغ أو تمريره إلى المَعلمة allowCredentials
في navigator.credentials.get()
.
async function authenticate() {
// ...
const publicKeyCredentialRequestOptions = {
// Server generated challenge:
challenge: ****,
// The same RP ID as used during registration:
rpId: 'example.com',
// You can omit `allowCredentials` as well:
allowCredentials: []
};
const credential = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
إظهار ميزة الملء التلقائي لنموذج مفتاح المرور
يعمل أداة اختيار الحسابات المعروضة في نافذة منبثقة والموضّحة أعلاه بشكل جيد إذا كان معظم المستخدمين يستخدمون مفاتيح المرور وتتوفر لديهم على الجهاز المحلي. بالنسبة إلى المستخدم الذي لا يملك مفاتيح مرور على الجهاز، سيظل مربّع الحوار المنبثق ظاهرًا وسيطلب من المستخدم تقديم مفتاح مرور من جهاز آخر. أثناء نقل المستخدمين إلى مفاتيح المرور، قد تحتاج إلى تجنُّب واجهة المستخدم هذه للمستخدمين الذين لم يسبق لهم إعداد مفتاح مرور.
بدلاً من ذلك، يمكن دمج اختيار مفتاح المرور في طلبات الملء التلقائي للحقول في نموذج تسجيل الدخول التقليدي، إلى جانب أسماء المستخدمين وكلمات المرور المحفوظة. بهذه الطريقة، يمكن للمستخدم الذي لديه مفاتيح مرور "ملء" نموذج تسجيل الدخول من خلال اختيار مفتاح المرور، ويمكن للمستخدمين الذين لديهم أزواج محفوظة من اسم المستخدم وكلمة المرور اختيارها، وسيظل بإمكان المستخدمين الذين ليس لديهم أي منهما كتابة اسم المستخدم وكلمة المرور.
هذه التجربة مثالية للمستخدمين عندما يكون RP قيد عملية نقل بيانات باستخدام كلمات المرور ومفاتيح المرور بشكل مختلط.
لتحقيق هذه التجربة للمستخدم، بالإضافة إلى تمرير صفيف فارغ إلى السمة allowCredentials
أو حذف المَعلمة، حدِّد mediation: 'conditional'
في navigator.credentials.get()
وشارِح حقل إدخال username
بتنسيق HTML باستخدام autocomplete="username webauthn"
أو حقل إدخال password
باستخدام autocomplete="password webauthn"
.
لن يؤدي طلب navigator.credentials.get()
إلى عرض أي واجهة مستخدم، ولكن إذا ركز المستخدم على حقل الإدخال الذي يحتوي على تعليقات توضيحية، سيتم تضمين أي مفاتيح مرور متاحة في خيارات الملء التلقائي. إذا اختار المستخدم أحدهما، سيخضع للتحقّق العادي من فتح قفل الجهاز، وعندها فقط سيتم حلّ الوعد الذي يعرضه .get()
بنتيجة. إذا لم يختار المستخدم مفتاح مرور، لن يتم حلّ الوعد مطلقًا.
async function authenticate() {
// ...
const publicKeyCredentialRequestOptions = {
// Server generated challenge:
challenge: ****,
// The same RP ID as used during registration:
rpId: 'example.com',
// You can omit `allowCredentials` as well:
allowCredentials: []
};
const cred = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal,
// Specify 'conditional' to activate conditional UI
mediation: 'conditional'
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
<input type="text" name="username" autocomplete="username webauthn" ...>
يمكنك التعرّف على كيفية إنشاء تجربة المستخدم هذه في تسجيل الدخول باستخدام مفتاح مرور من خلال ميزة الملء التلقائي للنموذج، بالإضافة إلى الدرس التطبيقي تنفيذ مفاتيح المرور باستخدام ميزة الملء التلقائي للنموذج في تطبيق ويب.
إعادة المصادقة
في بعض الحالات، مثل استخدام مفاتيح المرور لإعادة المصادقة، يكون معرّف المستخدم معروفًا. في هذه الحالة، نريد استخدام مفتاح مرور بدون أن يعرض المتصفّح أو نظام التشغيل أي شكل من أشكال أداة اختيار الحساب. ويمكن إجراء ذلك من خلال تمرير قائمة بأرقام تعريف بيانات الاعتماد في المَعلمة allowCredentials
.
في هذه الحالة، إذا كانت أي من بيانات الاعتماد المُسمّاة متاحة على الجهاز، سيُطلَب من المستخدم فتح قفل الجهاز على الفور. وإذا لم يكن الأمر كذلك، سيُطلب من المستخدم تقديم جهاز آخر (هاتف أو مفتاح أمان) يحتوي على بيانات اعتماد صالحة.
لتحقيق تجربة المستخدم هذه، قدِّم قائمة بأرقام تعريف بيانات الاعتماد للمستخدم الذي سجّل الدخول. من المفترض أن يتمكّن موفِّر المحتوى من طلب هذه المعلومات لأنّ المستخدم معروف. قدِّم أرقام تعريف بيانات الاعتماد كعناصر PublicKeyCredentialDescriptor
في السمة allowCredentials
في navigator.credentials.get()
.
async function authenticate() {
// ...
const publicKeyCredentialRequestOptions = {
// Server generated challenge:
challenge: ****,
// The same RP ID as used during registration:
rpId: 'example.com',
// Provide a list of PublicKeyCredentialDescriptors:
allowCredentials: [{
id: ****,
type: 'public-key',
transports: [
'internal',
'hybrid'
]
}, {
id: ****,
type: 'public-key',
transports: [
'internal',
'hybrid'
]
}, ...]
};
const credential = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
يتألف عنصر PublicKeyCredentialDescriptor
من:
id
: رقم تعريف بيانات اعتماد المفتاح العام التي حصلت عليها الجهة المحظورة عند تسجيل مفتاح المرورtype
: يكون هذا الحقل عادةً'public-key'
.-
transports
: تلميح بشأن وسائل النقل المتوافقة مع الجهاز الذي يحمل بيانات الاعتماد هذه، وتستخدمه المتصفّحات لتحسين واجهة المستخدم التي تطلب من المستخدم تقديم جهاز خارجي. يجب أن تحتوي هذه القائمة، في حال توفّرها، على نتيجة استدعاءgetTransports()
أثناء تسجيل كل بيانات اعتماد.
ملخّص
تجعل بيانات الاعتماد القابلة للاكتشاف تجربة تسجيل الدخول باستخدام مفتاح المرور أكثر سهولة للمستخدمين من خلال السماح لهم بتخطّي إدخال اسم مستخدم. من خلال الجمع بين residentKey
وrequireResidentKey
وallowCredentials
، يمكن لموفّري خدمات الدفع توفير تجارب تسجيل دخول:
- عرض أداة اختيار حساب في وضع النافذة المنبثقة
- عرض ميزة الملء التلقائي لنموذج مفتاح المرور
- إعادة المصادقة
استخدام بيانات الاعتماد القابلة للاكتشاف بحكمة ومن خلال إجراء ذلك، يمكنك تصميم تجارب تسجيل دخول متقدّمة باستخدام مفاتيح المرور تبدو سلسة للمستخدمين وتزيد من احتمال تفاعلهم مع التطبيق.