ข้อมูลอัปเดตของ FedCM: API สถานะการเข้าสู่ระบบ, API ข้อผิดพลาด และ Flag API ที่เลือกโดยอัตโนมัติ

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 จะแสดงข้อความที่แนะนำการลงชื่อเข้าใช้ ดังที่ปรากฏในรูปภาพต่อไปนี้

กล่องโต้ตอบ FedCM ที่แนะนำให้ลงชื่อเข้าใช้ IdP
กล่องโต้ตอบ FedCM ที่แนะนำให้ลงชื่อเข้าใช้ IdP

เมื่อผู้ใช้คลิกปุ่มดำเนินการต่อ เบราว์เซอร์จะเปิดกล่องโต้ตอบของหน้าเข้าสู่ระบบของ IdP

กล่องโต้ตอบตัวอย่าง
ตัวอย่างกล่องโต้ตอบที่แสดงหลังจากคลิกลงชื่อเข้าใช้ปุ่ม 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() เพื่อปิดกล่องโต้ตอบ
ผู้ใช้จะลงชื่อเข้าใช้ RP หลังจากลงชื่อเข้าใช้ IdP โดยใช้ FedCM
ผู้ใช้ลงชื่อเข้าใช้ RP หลังจากลงชื่อเข้าใช้ IdP โดยใช้ FedCM

คุณสามารถทดลองใช้ลักษณะการทำงานของ API สถานะการเข้าสู่ระบบได้ในการสาธิตของเรา

  1. แตะปุ่ม Go to IdP and sign in
  2. ลงชื่อเข้าใช้ด้วยบัญชีที่กำหนดเอง
  3. เลือกเซสชันหมดอายุจากเมนูแบบเลื่อนลงสถานะบัญชี
  4. กดปุ่มอัปเดตข้อมูลส่วนบุคคล
  5. แตะปุ่มไปที่ RP เพื่อลองใช้ FedCM

คุณควรสังเกตการเข้าสู่ระบบ IdP ได้จากลักษณะการทำงานของโมดูล

API ข้อผิดพลาด

เมื่อ Chrome ส่งคำขอไปยังปลายทางการยืนยันรหัส (เช่น เมื่อผู้ใช้คลิกปุ่มดำเนินการต่อในชื่อบน UI ของ FedCM หรือเรียกใช้การตรวจสอบสิทธิ์อีกครั้งโดยอัตโนมัติ) IdP อาจออกโทเค็นไม่ได้ด้วยเหตุผลทางกฎหมาย เช่น หากไคลเอ็นต์ไม่ได้รับอนุญาต เซิร์ฟเวอร์จะไม่พร้อมใช้งานชั่วคราว เป็นต้น ปัจจุบัน Chrome ดำเนินการตามคำขอโดยไม่แจ้งหากเกิดข้อผิดพลาดดังกล่าว และจะแจ้งให้ RP ทราบโดยการปฏิเสธคำมั่นสัญญาเท่านั้น

เมื่อใช้ Error API แล้ว Chrome จะแจ้งเตือนผู้ใช้ด้วยการแสดง UI แบบดั้งเดิมที่มีข้อมูลข้อผิดพลาดจาก IdP

กล่องโต้ตอบ FedCM ที่แสดงข้อความแสดงข้อผิดพลาดหลังจากที่ผู้ใช้พยายามลงชื่อเข้าใช้ไม่สำเร็จ สตริงจะเชื่อมโยงกับประเภทข้อผิดพลาด
กล่องโต้ตอบ FedCM ที่แสดงข้อความแสดงข้อผิดพลาดหลังจากพยายามลงชื่อเข้าใช้ของผู้ใช้ไม่สำเร็จ สตริงจะเชื่อมโยงกับประเภทข้อผิดพลาด

API HTTP สำหรับ IdP

ในการตอบกลับของ id_assertion_endpoint IdP สามารถคืนโทเค็นไปยังเบราว์เซอร์ได้หากสามารถออกให้ตามคําขอ ในข้อเสนอนี้ ในกรณีที่ไม่สามารถออกโทเค็นได้ IdP อาจตอบกลับเป็น "ข้อผิดพลาด" ซึ่งมีช่องที่ไม่บังคับใหม่ 2 ช่องดังนี้

  1. code
  2. 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