การอัปเดตบางอย่างที่อธิบายไว้ที่นี่มีคำอธิบายอยู่ในเซสชัน Google I/O เรื่องการลงชื่อเข้าใช้ที่ปลอดภัยและราบรื่น: คงการมีส่วนร่วมของผู้ใช้
Chrome 57
Chrome 57 ได้เปิดตัวการเปลี่ยนแปลงที่สําคัญนี้ใน Credential Management API
คุณสามารถแชร์ข้อมูลเข้าสู่ระบบจากโดเมนย่อยอื่นได้
ตอนนี้ Chrome สามารถดึงข้อมูลเข้าสู่ระบบที่จัดเก็บไว้ในโดเมนย่อยอื่นได้โดยใช้ Credential Management API
ตัวอย่างเช่น หากมีการจัดเก็บรหัสผ่านใน login.example.com
นั้น สคริปต์ใน www.example.com
จะแสดงรหัสผ่านดังกล่าวเป็นหนึ่งในรายการบัญชีในกล่องโต้ตอบเครื่องมือเลือกบัญชีได้
คุณต้องจัดเก็บรหัสผ่านโดยใช้ navigator.credentials.store()
อย่างชัดแจ้ง เพื่อให้ระบบส่งและคัดลอกรหัสผ่านไปยังต้นทางปัจจุบันเมื่อผู้ใช้เลือกข้อมูลเข้าสู่ระบบโดยการแตะกล่องโต้ตอบ
เมื่อจัดเก็บแล้ว รหัสผ่านจะพร้อมใช้งานเป็นข้อมูลเข้าสู่ระบบในต้นทางเดียวกันตั้งแต่www.example.com
เป็นต้นไป
ในภาพหน้าจอต่อไปนี้ ข้อมูลเข้าสู่ระบบที่เก็บไว้ภายใต้ login.aliexpress.com
จะแสดงให้ m.aliexpress.com
เห็นและพร้อมให้ผู้ใช้เลือก
Chrome 60
Chrome 60 มีการเปลี่ยนแปลงที่สําคัญหลายอย่างใน Credential Management API ดังนี้
ตอนนี้ออบเจ็กต์
PasswordCredential
มีรหัสผ่านแล้วเนื่องจากไม่จำเป็นต้องใช้ฟังก์ชัน
fetch()
ที่กําหนดเองเพื่อดึงข้อมูลรหัสผ่านอีกต่อไป เราจึงจะเลิกใช้งานฟังก์ชันนี้ในเร็วๆ นี้navigator.credentials.get()
ยอมรับ enummediation
แทน Flag แบบบูลีนunmediated
แล้วเปลี่ยนชื่อ
requireUserMediation()
เป็นpreventSilentAccess()
เมธอดใหม่
navigator.credentials.create()
สร้างออบเจ็กต์ข้อมูลเข้าสู่ระบบแบบไม่พร้อมกัน
การตรวจหาองค์ประกอบต้องดำเนินการ
หากต้องการตรวจสอบว่า Credential Management API สําหรับการเข้าถึงข้อมูลเข้าสู่ระบบที่ใช้รหัสผ่านและข้อมูลเข้าสู่ระบบที่รวมศูนย์พร้อมใช้งานหรือไม่ ให้ตรวจสอบว่า window.PasswordCredential
หรือ window.FederatedCredential
พร้อมใช้งานหรือไม่
if (window.PasswordCredential || window.FederatedCredential) {
// The Credential Management API is available
}
ตอนนี้ออบเจ็กต์ PasswordCredential
มีรหัสผ่านแล้ว
Credential Management API ใช้แนวทางที่อนุรักษ์นิยมในการจัดการรหัสผ่าน
ซึ่งจะปกปิดรหัสผ่านจาก JavaScript โดยกำหนดให้นักพัฒนาแอปส่งออบเจ็กต์ PasswordCredential
ไปยังเซิร์ฟเวอร์โดยตรงเพื่อตรวจสอบผ่านส่วนขยายของ fetch()
API
แต่วิธีการนี้มีข้อจํากัดหลายประการ เราได้รับความคิดเห็นว่านักพัฒนาแอปใช้ API ไม่ได้เนื่องจากสาเหตุต่อไปนี้
โดยต้องส่งรหัสผ่านเป็นส่วนหนึ่งของออบเจ็กต์ JSON
ผู้ใช้ต้องส่งค่าแฮชของรหัสผ่านไปยังเซิร์ฟเวอร์
หลังจากทำการวิเคราะห์ความปลอดภัยและพบว่าการปกปิดรหัสผ่านจาก JavaScript ไม่ได้ป้องกันเวกเตอร์การโจมตีทั้งหมดได้อย่างมีประสิทธิภาพตามที่คาดหวัง เราจึงตัดสินใจที่จะเปลี่ยนแปลง
ตอนนี้ Credential Management API มีรหัสผ่านดิบอยู่ในออบเจ็กต์ข้อมูลเข้าสู่ระบบที่แสดงผลแล้ว เพื่อให้คุณเข้าถึงรหัสผ่านในรูปแบบข้อความธรรมดาได้ คุณสามารถใช้วิธีการที่มีอยู่เพื่อส่งข้อมูลเข้าสู่ระบบไปยังเซิร์ฟเวอร์ได้ ดังนี้
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()
ยอมรับสื่อกลางแบบ Enum แล้ว
จนถึง Chrome 60
navigator.credentials.get()
ยอมรับพร็อพเพอร์ตี้ unmediated
ที่ไม่บังคับ
ด้วย Flag บูลีน เช่น
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
unmediated: true
}).then(c => {
// Sign-in
});
การตั้งค่า unmediated: true
ป้องกันไม่ให้เบราว์เซอร์แสดงเครื่องมือเลือกบัญชีเมื่อส่งข้อมูลเข้าสู่ระบบ
ตอนนี้การแจ้งว่าไม่เหมาะสมได้ขยายการให้บริการเป็นสื่อกลางแล้ว การสื่อกลางของผู้ใช้อาจเกิดขึ้นในกรณีต่อไปนี้
ผู้ใช้ต้องเลือกบัญชีที่จะลงชื่อเข้าใช้
ผู้ใช้ต้องการลงชื่อเข้าใช้อย่างชัดเจนหลังจาก
navigator.credentials.requireUseMediation()
โทร
เลือกตัวเลือกใดตัวเลือกหนึ่งต่อไปนี้สำหรับค่า mediation
ค่า mediation |
เมื่อเทียบกับ Flag แบบบูลีน | พฤติกรรม | |
---|---|---|---|
silent |
เท่ากับ unmediated: true |
ส่งข้อมูลเข้าสู่ระบบโดยไม่ได้แสดงเครื่องมือเลือกบัญชี | |
optional |
เท่ากับ unmediated: false |
แสดงเครื่องมือเลือกบัญชีหากเรียกใช้ preventSilentAccess() ก่อนหน้านี้ |
|
required |
ตัวเลือกใหม่ | แสดงเครื่องมือเลือกบัญชีเสมอ มีประโยชน์เมื่อคุณต้องการอนุญาตให้ผู้ใช้เปลี่ยนบัญชีโดยใช้กล่องโต้ตอบตัวเลือกบัญชีแบบดั้งเดิม |
ในตัวอย่างนี้ ระบบจะส่งผ่านข้อมูลเข้าสู่ระบบโดยไม่แสดงเครื่องมือเลือกบัญชี ซึ่งเทียบเท่ากับ Flag ก่อนหน้า unmediated: true
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).then(c => {
// Sign-in
});
เปลี่ยนชื่อ requireUserMediation()
เป็น preventSilentAccess()
เราได้เปลี่ยนชื่อเมธอด navigator.credentials.requireUserMediation()
เป็น navigator.credentials.preventSilentAccess()
เพื่อให้สอดคล้องกับพร็อพเพอร์ตี้ mediation
ใหม่ที่เสนอในการเรียก get()
เมธอดที่เปลี่ยนชื่อจะป้องกันไม่ให้ส่งข้อมูลเข้าสู่ระบบโดยไม่แสดงเครื่องมือเลือกบัญชี (บางครั้งเรียกว่า "ไม่มีสื่อกลางของผู้ใช้") ซึ่งจะมีประโยชน์เมื่อผู้ใช้ออกจากระบบเว็บไซต์หรือยกเลิกการลงทะเบียนในเว็บไซต์ และไม่ต้องการลงชื่อเข้าใช้อีกครั้งโดยอัตโนมัติเมื่อเข้าชมครั้งถัดไป
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 อยู่แล้วใช่ไหม เรามีเอกสารคำแนะนำในการย้ายข้อมูลไว้ให้คุณสามารถอัปเกรดเป็นเวอร์ชันใหม่