سنوضّح بعض التحديثات الموضَّحة هنا في جلسة مؤتمر Google I/O بعنوان تسجيل الدخول الآمن والسلس: الحفاظ على تفاعل المستخدمين:
Chrome 57
أدخل Chrome 57 هذا التغيير المهم في Credential Management API.
يمكن مشاركة بيانات الاعتماد من نطاق فرعي مختلف.
يمكن لمتصفِّح Chrome الآن استرداد بيانات اعتماد تم تخزينها في نطاق فرعي مختلف باستخدام واجهة برمجة تطبيقات إدارة بيانات الاعتماد.
على سبيل المثال، في حال تخزين كلمة مرور في login.example.com
،
يمكن للنص البرمجي في www.example.com
عرضه كأحد عناصر الحساب في مربّع حوار "أداة اختيار الحساب".
يجب تخزين كلمة المرور بشكل صريح باستخدام navigator.credentials.store()
، بحيث عندما يختار المستخدم بيانات اعتماد عن طريق النقر على مربع الحوار، يتم تمرير كلمة المرور ونسخها إلى الأصل الحالي.
بعد تخزينها، تتوفّر كلمة المرور كبيانات اعتماد من المصدر نفسه من www.example.com
فصاعدًا.
في لقطة الشاشة التالية، معلومات بيانات الاعتماد المخزّنة ضمن login.aliexpress.com
مرئية لـ m.aliexpress.com
ومتاحة للمستخدم للاختيار من بينها:
![أداة اختيار الحساب تعرض تفاصيل تسجيل الدخول إلى النطاق الفرعي المحدّد](https://developer.chrome.google.cn/static/blog/credential-management-updates/image/account-chooser-showing-s-369ff3f4bb61e.png?authuser=6&hl=ar)
إصدار 60 من Chrome
يقدّم Chrome 60 العديد من التغييرات المهمة على Credential Management API:
بما أنّ دالة
fetch()
المخصّصة لم تعُد مطلوبة لاسترجاع كلمة المرور، سيتم إيقافها نهائيًا قريبًا.تقبل الإضافة
navigator.credentials.get()
الآن التعدادmediation
بدلاً من العلامة المنطقيةunmediated
.تمت إعادة تسمية المكان "
requireUserMediation()
" إلى "preventSilentAccess()
".تؤدي الطريقة الجديدة
navigator.credentials.create()
إلى إنشاء كائنات بيانات الاعتماد بشكل غير متزامن.
رصد الميزات يستدعي الانتباه.
لمعرفة ما إذا كانت واجهة برمجة تطبيقات إدارة بيانات الاعتماد للوصول إلى بيانات الاعتماد المستندة إلى كلمة المرور وبيانات الاعتماد الموحّدة متاحة، تحقَّق من توفُّر window.PasswordCredential
أو window.FederatedCredential
.
if (window.PasswordCredential || window.FederatedCredential) {
// The Credential Management API is available
}
يحتوي العنصر "PasswordCredential
" الآن على كلمة مرور.
اتّبعت واجهة برمجة تطبيقات إدارة بيانات الاعتماد منهجًا متحفظًا في التعامل مع كلمات المرور.
أخفيت كلمات المرور من JavaScript، ما يتطلّب من المطوّرين
إرسال عنصر PasswordCredential
مباشرةً إلى خادمهم
للتحقّق من صحتهم من خلال إضافة إلى fetch()
API.
غير أن هذا المنهج قدم عددًا من القيود. لقد تلقّينا ملاحظات تفيد بأنّه لم يتمكّن المطوّرون من استخدام واجهة برمجة التطبيقات للسببَين التاليَين:
كان عليهم إرسال كلمة المرور كجزء من عنصر JSON.
وكان عليهم إرسال قيمة تجزئة كلمة المرور إلى خادمهم.
بعد إجراء تحليل أمني وإدراكك أن إخفاء كلمات المرور من JavaScript لم يمنع جميع متجهات الهجوم بالفعالية التي كنا نأملها، قررنا إجراء تغيير.
تشتمل واجهة برمجة تطبيقات إدارة بيانات الاعتماد الآن على كلمة مرور أولية في كائن بيانات اعتماد تم عرضه حتى تتمكن من الوصول إليه كنص عادي. يمكنك استخدام الطرق الحالية لإرسال معلومات الاعتماد إلى الخادم:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).then(passwordCred => {
if (passwordCred) {
let form = new FormData();
form.append('email', passwordCred.id);
form.append('password', passwordCred.password);
form.append('csrf_token', csrf_token);
return fetch('/signin', {
method: 'POST',
credentials: 'include',
body: form
});
} else {
// Fallback to sign-in form
}
}).then(res => {
if (res.status === 200) {
return res.json();
} else {
throw 'Auth failed';
}
}).then(profile => {
console.log('Auth succeeded', profile);
});
سيتم إيقاف العمل بميزة "الجلب المخصص" قريبًا
لتحديد ما إذا كنت تستخدم دالة fetch()
مخصّصة، يُرجى التأكّد مما إذا كانت تستخدم كائن PasswordCredential
أو كائن FederatedCredential
كقيمة للسمة credentials
، على سبيل المثال:
fetch('/signin', {
method: 'POST',
credentials: c
})
ويُنصح باستخدام دالة fetch()
عادية كما هو موضّح في المثال السابق للرمز، أو استخدام XMLHttpRequest
.
تقبل ميزة "navigator.credentials.get()
" الآن توسّط التعداد.
قبل استخدام الإصدار 60 من Chrome،
كان navigator.credentials.get()
يقبل سمة unmediated
اختيارية
مع علامة منطقية. مثال:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
unmediated: true
}).then(c => {
// Sign-in
});
يمنع ضبط unmediated: true
المتصفّح من عرض أداة اختيار الحساب
عند تمرير بيانات اعتماد.
تم تمديد العلامة الآن كتوسّط. يمكن أن يحدث توسّط المستخدِم في الحالات التالية:
يحتاج المستخدم إلى اختيار حساب لتسجيل الدخول من خلاله.
يريد أحد المستخدمين تسجيل الدخول صراحةً بعد مكالمة
navigator.credentials.requireUseMediation()
حدِّد أحد الخيارات التالية للقيمة mediation
:
قيمة mediation |
مقارنةً بالعلامة المنطقية | السلوك | |
---|---|---|---|
silent |
يساوي unmediated: true |
تم تمرير بيانات الاعتماد بدون عرض أداة اختيار الحساب. | |
optional |
يساوي unmediated: false |
يعرض أداة اختيار الحساب في حال تم الاتصال بـ "preventSilentAccess() " مسبقًا. |
|
required |
خيار جديد | عرض أداة اختيار الحساب دائمًا يكون هذا الخيار مفيدًا عندما تريد السماح لمستخدم بتبديل حساب باستخدام مربّع حوار أداة اختيار الحساب الأصلي. |
في هذا المثال، يتم تمرير بيانات الاعتماد بدون إظهار محدد الحساب، الذي يكافئ العلامة السابقة unmediated: true
:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).then(c => {
// Sign-in
});
تمت إعادة تسمية "requireUserMediation()
" إلى "preventSilentAccess()
".
للتوافق بشكل جيد مع السمة mediation
الجديدة التي تم توفيرها في الطلب get()
،
تمت إعادة تسمية الطريقة navigator.credentials.requireUserMediation()
إلى
navigator.credentials.preventSilentAccess()
.
تمنع الطريقة المُعاد تسميتها تمرير بيانات الاعتماد بدون عرض أداة اختيار الحساب (وتسمى أحيانًا بدون توسّط المستخدم). يفيد ذلك عندما يسجّل المستخدم الخروج من أحد المواقع الإلكترونية أو يلغي التسجيل من أحد المواقع الإلكترونية ولا يريد إعادة تسجيل الدخول تلقائيًا في الزيارة التالية.
signoutUser();
if (navigator.credentials) {
navigator.credentials.preventSilentAccess();
}
إنشاء عناصر بيانات اعتماد بشكلٍ غير متزامن باستخدام الطريقة الجديدة navigator.credentials.create()
يمكنك الآن إنشاء كائنات بيانات الاعتماد بشكل غير متزامن
باستخدام الطريقة الجديدة navigator.credentials.create()
.
تابع القراءة للاطّلاع على مقارنة بين نهج المزامنة والنهج غير المتزامن.
جارٍ إنشاء عنصر "PasswordCredential
"
طريقة المزامنة
let c = new PasswordCredential(form);
أسلوب غير متزامن (جديد)
let c = await navigator.credentials.create({
password: form
});
أو:
let c = await navigator.credentials.create({
password: {
id: id,
password: password
}
});
جارٍ إنشاء عنصر "FederatedCredential
"
طريقة المزامنة
let c = new FederatedCredential({
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
});
أسلوب غير متزامن (جديد)
let c = await navigator.credentials.create({
federated: {
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
}
});
دليل نقل البيانات
هل لديك تطبيق حالي لـ Credential Management API؟ لدينا مستند دليل نقل البيانات يمكنك اتباعه للترقية إلى الإصدار الجديد.