ข้อมูลอัปเดตบางส่วนที่อธิบายไว้ที่นี่มีอธิบายไว้ในเซสชัน 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 ดังนี้
เนื่องจากไม่จำเป็นต้องใช้ฟังก์ชัน
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 ไม่ได้ป้องกันเวกเตอร์การโจมตีทั้งหมดได้อย่างมีประสิทธิภาพตามที่คาดหวัง เราจึงตัดสินใจที่จะทำการเปลี่ยนแปลง
ตอนนี้ 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 อยู่แล้วใช่ไหม เรามีเอกสารคำแนะนำในการย้ายข้อมูลที่คุณสามารถทำตามเพื่ออัปเกรดเป็นเวอร์ชันใหม่ได้