Chrome 120 กำลังจัดส่ง API สถานะการเข้าสู่ระบบสำหรับ FedCM API สถานะการเข้าสู่ระบบ (เดิมเรียกว่า API สถานะการลงชื่อเข้าใช้ IdP) ช่วยให้เว็บไซต์ (โดยเฉพาะผู้ให้บริการข้อมูลประจำตัว) ส่งสัญญาณไปยังเบราว์เซ��ร์เมื่อผู้ใช้เข้าสู่ระบบและออกจากระบบ FedCM ใช้สัญญาณนี้เพื่อจัดการกับปัญหาการโจมตีแบบแทรกเวลาแบบเงียบ การทำเช่นนั้นจึงทำให้ FedCM ทำงานโดยไม่มีคุกกี้ของบุคคลที่สามโดยสิ้นเชิง การอัปเดตนี้จะกล่าวถึงการเปลี่ยนแปลงล่าสุดที่เข้ากันไม่ได้แบบย้อนหลังซึ่งเราระบุไว้ก่อนหน้านี้ใน Intent to Ship of FedCM เดิมซึ่งเป็นส่วนหนึ่งของขอบเขตงานของเรา
แม้ว่า API สถานะการเข้าสู่ระบบจะปรับปรุงพร็อพเพอร์ตี้ความเป็นส่วนตัวและความสามารถในการใช้งาน แต่เมื่อจัดส่งแล้ว Google จะใช้การเปลี่ยนแปลงที่เข้ากันไม่ได้แบบย้อนหลัง หากคุณใช้งาน FedCM อยู่แล้ว โปรดอัปเดตโดยใช้คำแนะนำต่อไปนี้
นอกจากนี้ Chrome จะมีฟีเจอร์ใหม่ Federated Credential Management (FedCM) 2 ฟีเจอร์ ดังนี้
- Error API: แจ้งเตือนผู้ใช้เมื่อลงชื่อเข้าใช้ไม่สำเร็จด้วย UI แบบเนทีฟตามการตอบสนองของเซิร์ฟเวอร์จากปลายทางการยืนยันรหัส (หากมี)
- Auto-Selected Flag API: แจ้งผู้ให้บริการข้อมูลประจำตัว (IdP) และฝ่ายที่เกี่ยวข้อง (RP) หากมีการเลือกข้อมูลเข้าสู่ระบบโดยอัตโนมัติในขั้นตอนดังกล่าว
API สถานะการเข้าสู่ระบบ
API สถานะการเข้าสู่ระบบคือกลไกที่เว็บไซต์ โดยเฉพาะ IdP จะแจ้งสถานะการเข้าสู่ระบบของผู้ใช้บน IdP ให้กับเบราว์เซอร์ เมื่อใช้ API นี้ เบราว์เซอร์จะลดคำขอที่ไม่จำเป็นที่ส่งไปยัง IdP และลดการโจมตีด้านเวลาที่อาจเกิดขึ้น
แจ้งเบราว์เซอร์เกี่ยวกับสถานะการเข้าสู่ระบบของผู้ใช้
โดย IdP จะส่งสัญญาณแจ้งสถานะการเข้าสู่ระบบของผู้ใช้ไปยังเบราว์เซอร์ได้โดยการส่งส่วนหัว HTTP หรือโดยการเรียกใช้ JavaScript API เมื่อผู้ใช้ลงชื่อเข้าใช้ใน IdP หรือเมื่อผู้ใช้ออกจากระบบบัญชี IdP ทั้งหมด สำหรับ IdP แต่ละรายการ (ระบุโดย URL การกำหนดค่า) เบราว์เซอร์จะเก็บตัวแปร Tri-state ที่แสดงถึงสถานะการเข้าสู่ระบบด้วยค่าที่เป็นไปได้ logged-in
, logged-out
และ unknown
สถานะเริ่มต้นคือ unknown
หากต้องการส่งสัญญาณว่าผู้ใช้ลงชื่อเข้าใช้แล้ว ให้ส่งส่วนหัว HTTP ของ Set-Login: logged-in
ในการนำทางระดับบนสุดหรือคำขอทรัพยากรย่อยที่มีต้นทางเดียวกัน โดยทำดังนี้
Set-Login: logged-in
หรือเรียก JavaScript API navigator.login.setStatus('logged-in')
จากต้นทาง IdP โดยใช้คำสั่งต่อไปนี้
navigator.login.setStatus('logged-in');
การโทรเหล่านี้จะบันทึก��ถานะการเข้าสู่ระบบของผู้ใช้เป็น logged-in
เมื่อตั้งค่าสถานะการเข้าสู่ระบบของผู้ใช้เป็น logged-in
การเรียกใช้ RP ที่ FedCM จะส่งคำขอไปยังปลายทางรายการบัญชีของ IdP และแสดงบัญชีที่พร้อมใช้งานแก่ผู้ใช้ในกล่องโต้ตอบของ FedCM
หากต้องการส่งสัญญาณว่าผู้ใช้ออกจากระบบบัญชีทั้งหมด ให้ส่งส่วนหัว HTTP ของ Set-Login:
logged-out
ในการนำทางระดับบนสุดหรือคำขอทรัพยากรย่อยที่มีต้นทางเดียวกัน โดยทำดังนี้
Set-Login: logged-out
หรือเรียก JavaScript API navigator.login.setStatus('logged-out')
จากต้นทาง IdP โดยใช้คำสั่งต่อไปนี้
navigator.login.setStatus('logged-out');
การโทรเหล่านี้จะบันทึกสถานะการเข้าสู่ระบบของผู้ใช้เป็น logged-out
เมื่อสถานะการเข้าสู่ระบบของผู้ใช้คือ logged-out
การเรียกใช้ FedCM จะล้มเหลวโดยไม่ต้องส่งคำขอไปยังปลายทางรายการบัญชีของ IdP
ระบบจะตั้งค่าสถานะ unknown
ก่อนที่ IdP จะส่งสัญญาณโดยใช้ API สถานะการเข้าสู่ระบบ เรานำสถานะนี้มาใช้เพื่อให้การเปลี่ยนผ่านที่ดียิ่งขึ้นเนื่องจากผู้ใช้อาจลงชื่อเข้าใช้ IdP แล้วเมื่อเราจัดส่ง API นี้ IdP อาจไม่มีโอกาสส่งสัญญาณนี้ไปยังเบราว์เซอร์เมื่อมีการเรียกใช้ FedCM ครั้งแรก ในกรณีนี้ เราจะส่งคำขอไปยังปลายทางรายการบัญชีของ IdP และอัปเดตสถานะตามการตอบสนองจากปลายทางรายการบัญชี
- หากปลายทางแสดงรายการบัญชีที่ใช้งานอยู่ ให้อัปเดตสถานะเป็น
logged-in
และเปิดกล่องโต้ตอบ FedCM เพื่อแสดงบัญชีเหล่านั้น - หากปลายทางไม่พบบัญชี ให้อัปเดตสถานะเป็น
logged-out
และดำเนินการเรียก FedCM ไม่สำเร็จ
จะเกิดอะไรขึ้นหากเซสชันของผู้ใช้หมดอายุ ให้ผู้ใช้ลงชื่อเข้าใช้ผ่านขั้นตอนการเข้าสู่ระบบแบบไดนามิก
แม้ว่า IdP จะแจ้งสถานะการเข้าสู่ระบบของผู้ใช้ให้เบราว์เซอร์ทราบอยู่เสมอ แต่สถานะอาจไม่ซิงค์กัน เช่น เมื่อเซสชันหมดอายุ เบราว์เซอร์จะพยายามส่งคำขอที่มีข้อมูลเข้าสู่ระบบไปยังปลายทางรายการบัญชีเมื่อสถานะการเข้าสู่ระบบคือ logged-in
แต่เซิร์ฟเวอร์ไม่ส่งกลับบัญชีใดๆ เนื่องจากเซสชันไม่พร้อมใช้งานอีกต่อไป ในสถานการณ์เช่นนี้ เบราว์เซอร์จะอนุญาตให้ผู้ใช้ลงชื่อเข้าใช้ IdP ได้แบบไดนามิกผ่านหน้าต่างกล่องโต้ตอบ
กล่องโต้ตอบ FedCM จะแสดงข้อความที่แนะนำการลงชื่อเข้าใช้ ดังที่ปรากฏในรูปภาพต่อไปนี้
เมื่อผู้ใช้คลิกปุ่มดำเนินการต่อ เบราว์เซอร์จะเปิดกล่องโต้ตอบของหน้าเข้าสู่ระบบของ IdP
URL ของหน้าเข้าสู่ระบบจะระบุด้วย login_url
เป็นส่วนหนึ่งของไฟล์การกำหนดค่า IdP
{
"accounts_endpoint": "/auth/accounts",
"client_metadata_endpoint": "/auth/metadata",
"id_assertion_endpoint": "/auth/idtokens",
"login_url": "/login"
}
}
กล่องโต้ตอบคือหน้าต่างเบราว์เซอร์ทั่วไปที่มีคุกกี้ของบุคคลที่หนึ่ง สิ่งที่เกิดขึ้นภายในกล่องโต้ตอบจะขึ้นอยู่กับ IdP และไม่มีแฮนเดิลหน้าต่างสำหรับส่งคำขอการสื่อสารแบบข้ามต้นทางไปยังหน้า RP หลังจากที่ผู้ใช้ลงชื่อเข้าใช้แล้ว IdP ควรทำดังนี้
- ส่งส่วนหัว
Set-Login: logged-in
หรือเรียกใช้navigator.login.setStatus("logged-in")
API เพื่อแจ้งให้เบราว์เซอร์ทราบว่าผู้ใช้ลงชื่อเข้าใช้แล้ว - โทรไปที่
IdentityProvider.close()
เพื่อปิดกล่องโต้ตอบ
คุณสามารถทดลองใช้ลักษณะการทำงานของ API สถานะการเข้าสู่ระบบได้ในการสาธิตของเรา
- แตะปุ่ม Go to IdP and sign in
- ลงชื่อเข้าใช้ด้วยบัญชีที่กำหนดเอง
- เลือกเซสชันหมดอายุจากเมนูแบบเลื่อนลงสถานะบัญชี
- กดปุ่มอัปเดตข้อมูลส่วนบุคคล
- แตะปุ่มไปที่ RP เพื่อลองใช้ FedCM
คุณควรสังเกตการเข้าสู่ระบบ IdP ได้จากลักษณะการทำงานของโมดูล
API ข้อผิดพลาด
เมื่อ Chrome ส่งคำขอไปยังปลายทางการยืนยันรหัส (เช่น เมื่อผู้ใช้คลิกปุ่มดำเนินการต่อในชื่อบน UI ของ FedCM หรือเรียกใช้การตรวจสอบสิทธิ์อีกครั้งโดยอัตโนมัติ) IdP อาจออกโทเค็นไม่ได้ด้วยเหตุผลทางกฎหมาย เช่น หากไคลเอ็นต์ไม่ได้รับอนุญาต เซิร์ฟเวอร์จะไม่พร้อมใช้งานชั่วคราว เป็นต้น ปัจจุบัน Chrome ดำเนินการตามคำขอโดยไม่แจ้งหากเกิดข้อผิดพลาดดังกล่าว และจะแจ้งให้ RP ทราบโดยการปฏิเสธคำมั่นสัญญาเท่านั้น
เมื่อใช้ Error API แล้ว Chrome จะแจ้งเตือนผู้ใช้ด้วยการแสดง UI แบบดั้งเดิมที่มีข้อมูลข้อผิดพลาดจาก IdP
API HTTP สำหรับ IdP
ในการตอบกลับของ id_assertion_endpoint
IdP สามารถคืนโทเค็นไปยังเบราว์เซอร์ได้หากสามารถออกให้ตามคําขอ ในข้อเสนอนี้ ในกรณีที่ไม่สามารถออกโทเค็นได้ IdP อาจตอบกลับเป็น "ข้อผิดพลาด" ซึ่งมีช่องที่ไม่บังคับใหม่ 2 ช่องดังนี้
code
url
// id_assertion_endpoint response
{
"error": {
"code": "access_denied",
"url": "https://idp.example/error?type=access_denied"
}
}
สำหรับรหัส IdP สามารถเลือกข้อผิดพลาดที่ทราบจากรายการข้อผิดพลาดที่ระบุ OAuth 2.0 [invalid_request
, unauthorized_client
, access_denied
, server_error
และ temporarily_unavailable
] หรือใช้สตริงที่กำหนดเองก็ได้ หากเป็นกรณีหลัง Chrome จะแสดงผล UI ข้อผิดพลาดพร้อมด้วยข้อความแสดงข้อผิดพลาดทั่วไปและส่งรหัสไปยัง RP
สำหรับ url
พารามิเตอร์จะระบุหน้าเว็บที่มนุษย์อ่านได้ซึ่งมีข้อมูลเกี่ยวกับข้อผิดพลาดเพื่อให้ข้อมูลเพิ่มเติมเกี่ยวกับข้อผิดพลาดแก่ผู้ใช้ ช่องนี้มีประโยชน์ต่อผู้ใช้เนื่องจากเบราว์เซอร์แสดงข้อความแสดงข้อผิดพลาดใน UI แบบเนทีฟไม่ได้ เช่น ลิงก์สำหรับขั้นตอนถัดไป ข้อมูลติดต่อฝ่ายบริการลูกค้า และอื่นๆ หากผู้ใช้ต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับรายละเอียดของข้อผิดพลาดและวิธีแก้ไข ก็สามารถไปที่หน้าที่ให้ไว้จาก UI ของเบราว์เซอร์เพื่อดูรายละเอียดเพิ่มเติมได้ URL ต้องเป็นเว็บไซต์เดียวกับ IdP configURL
try {
const cred = await navigator.credentials.get({
identity: {
providers: [
{
configURL: 'https://idp.example/manifest.json',
clientId: '1234',
},
],
}
});
} catch (e) {
const code = e.code;
const url = e.url;
}
API การตั้งค่าสถานะที่เลือกโดยอัตโนมัติ
mediation: optional
เป็นลักษณะการทำงานเริ่มต้นของสื่อกลางของผู้ใช้ใน API การจัดการข้อมูลเข้าสู่ระบบ และจะทริกเกอร์การตรวจสอบสิทธิ์อีกครั้งโดยอัตโนมัติเมื่อเป็นไปได้ อย่างไรก็ตาม การตรวจสอบสิทธิ์ซ้ำอัตโนมัติอาจใช้งานไม่ได้ด้วยเหตุผลที่มีเพียงเบราว์เซอร์เท่านั้นที่รู้ และเมื่อไม่พร้อมใช้งาน ผู้ใช้อาจได้รับแจ้งให้ลงชื่อเข้าใช้ด้วยสื่อกลางที่ชัดเจนของผู้ใช้ ซึ่งเป็นขั้นตอนที่กับพร็อพเพอร์ตี้แตกต่างกัน
- จากมุมมองของผู้โทร API เมื่อได้รับโทเค็นรหัส ผู้โทรจะไม่เห็นว่าการกระทำดังกล่าวเป็นผลลัพธ์ของขั้นตอนการตรวจสอบสิทธิ์ซ้ำอัตโนมัติหรือไม่ ซึ่งทำให้ประเมินประสิทธิภาพของ API และปรับปรุง UX ให้สอดคล้องกันได้ยาก
- จากมุมมองของ IdP พวกเขาไม่สามารถบอกได้ว่าการตรวจสอบสิทธิ์ซ้ำโดยอัตโนมัติเก��ดขึ้นหรือไม่สำหรับการประเมินประสิทธิภาพ นอกจากนี้ การมีสื่อกลางของผู้ใช้อย่างชัดแจ้งเข้ามาเกี่ยวข้องจะช่วยสนับสนุนฟีเจอร์ด้านความปลอดภัยเพิ่มเติมหรือไม่ ตัวอย่างเช่น ผู้ใช้บางรายอาจต้องการระดับการรักษาความปลอดภัยที่สูงขึ้น ซึ่งต้องมีสื่อกลางผู้ใช้อย่างชัดแจ้งในการตรวจสอบสิทธิ์ หาก IdP ได้รับคำขอโทเค็นโดยไ��่มีสื่อกลางดังกล่าว ก็จะจัดการคำขอได้ต่างออกไป เช่น แสดงรหัสข้อผิดพลาดเพื่อให้ RP เรียกใช้ FedCM API ได้อีกครั้งด้วย
mediation: required
ดังนั้น การมอบระดับการเข้าถึงขั้นตอนการตรวจสอบสิทธิ์ซ้ำอัตโนมัติจึงเป็นประโยชน์ต่อนักพัฒนาแอป
เมื่อใช้ Flag API ที่เลือกโดยอัตโนมัติ Chrome จะแชร์ว่าได้รับสิทธิ์จากผู้ใช้อย่างชัดแจ้งหรือไม่โดยการแตะปุ่มดำเนินการต่อในชื่อกับทั้ง IdP และ RP เมื่อใดก็ตามที่มีการตรวจสอบสิทธิ์ซ้ำโดยอัตโนมัติหรือเกิดสื่อกลางที่อาจไม่เหมาะสม การแชร์จะเกิดขึ้นหลังจากได้รับสิทธิ์ของผู้ใช้สำหรับการสื่อสาร IdP/RP เท่านั้น
การแชร์ IdP
หากต้องการแชร์ข้อมูลไปยังสิทธิ์ผู้ใช้สำหรับโพสต์ของ IdP Chrome จะรวม is_auto_selected=true
ในคำขอ POST
ที่ส่งไปยัง id_assertion_endpoint
POST /fedcm_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
account_id=123&client_id=client1234&nonce=Ct0D&disclosure_text_shown=true&is_auto_selected=true
การแชร์ RP
เบราว์เซอร์แชร์ข้อมูลให้ RP ใน isAutoSelected
ได้ผ่าน IdentityCredential
const cred = await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/manifest.json',
clientId: '1234'
}]
}
});
if (cred.isAutoSelected !== undefined) {
const isAutoSelected = cred.isAutoSelected;
}
มีส่วนร่วมและแชร์ความคิดเห็น
หากมีความคิดเห็นหรือพบปัญหาระหว่างการทดสอบ ก็แชร์ความคิดเห็นได้ที่ crbug.com
รูปภาพโดย Girl with red hatใน Unsplash