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

Chrome 120 มาพร้อมกับ Login Status API สำหรับ FedCM Login Status API (เดิมเรียกว่า IdP Sign-in Status API) ช่วยให้เว็บไซต์ โดยเฉพาะผู้ให้บริการข้อมูลประจำตัว ส่งสัญญาณไปยังเบราว์เซอร์เมื่อผู้ใช้เข้าสู่ระบบและออกจากระบบ FedCM ใช้สัญญาณนี้เพื่อแก้ปัญหาการโจมตีแบบกำหนดเวลาแบบเงียบ ซึ่งช่วยให้ FedCM ทำงานได้โดยไม่ต้องใช้คุกกี้ของบุคคลที่สามเลย การปรับปรุงนี้แก้ไขการเปลี่ยนแปลงที่ไม่เข้ากันได้กับเวอร์ชันเก่าที่เหลืออยู่ซึ่งเราระบุไว้ในความตั้งใจเดิมที่จะเปิดตัว FedCM ก่อนหน้านี้ โดยเป็นส่วนหนึ่งของขอบเขตงาน

แม้ว่า Login Status API จะปรับปรุงพร็อพเพอร์ตี้ความเป็นส่วนตัวและความสามารถในการใช้งาน แต่การเปลี่ยนแปลงนี้จะไม่เข้ากันได้กับเวอร์ชันเก่าเมื่อเผยแพร่ หากคุณมีการใช้งาน FedCM อยู่แล้ว โปรดอัปเดตโดยใช้วิธีการต่อไปนี้

นอกจากนี้ Chrome ยังเปิดตัวฟีเจอร์ Federated Credential Management (FedCM) ใหม่ 2 รายการ ได้แก่

  • Error API: แจ้งให้ผู้ใช้ทราบเมื่อพยายามลงชื่อเข้าใช้ไม่สำเร็จด้วย UI เดิม โดยอิงตามการตอบกลับจากเซิร์ฟเวอร์จากปลายทางการยืนยันผ่านบัตรประจำตัว (หากมี)
  • Auto-Selected Flag API: แจ้งผู้ให้บริการข้อมูลประจำตัว (IdP) และฝ่ายที่เชื่อถือ (RP) หากระบบเลือกข้อมูลเข้าสู่ระบบโดยอัตโนมัติในขั้นตอน

Login Status API

Login Status API เป็นกลไกที่เว็บไซต์ โดยเฉพาะ IdP จะแจ้งสถานะการเข้าสู่ระบบของผู้ใช้ใน IdP ไปยังเบราว์เซอร์ API นี้ช่วยให้เบราว์เซอร์สามารถลดคําขอที่ไม่จําเป็นไปยัง IdP และลดการโจมตีตามจังหวะเวลาได้

แจ้งให้เบราว์เซอร์ทราบเกี่ยวกับสถานะการเข้าสู่ระบบของผู้ใช้

IdP สามารถส่งสัญญาณสถานะการเข้าสู่ระบบของผู้ใช้ไปยังเบราว์เซอร์โดยการส่งส่วนหัว HTTP หรือโดยการเรียกใช้ JavaScript API เมื่อผู้ใช้ลงชื่อเข้าใช้ IdP หรือเมื่อผู้ใช้ออกจากระบบบัญชี IdP ทั้งหมด สําหรับ IdP แต่ละรายการ (ระบุโดย URL ของการกำหนดค่า) เบราว์เซอร์จะเก็บตัวแปรแบบ 3 สถานะซึ่งแสดงสถานะการเข้าสู่ระบบไว้ โดยมีค่าที่เป็นไปได้คือ logged-in, logged-out และ unknown สถานะเริ่มต้นคือ unknown

หากต้องการส่งสัญญาณว่าผู้ใช้ลงชื่อเข้าใช้แล้ว ให้ส่งSet-Login: logged-inส่วนหัว HTTP ในการนําทางระดับบนสุดหรือคําขอทรัพยากรย่อยจากแหล่งที่มาเดียวกัน ดังนี้

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

หากต้องการส่งสัญญาณว่าผู้ใช้ออกจากระบบบัญชีทั้งหมดแล้ว ให้ส่งSet-Login: logged-outส่วนหัว HTTP ในการนำทางระดับบนสุดหรือคำขอทรัพยากรย่อยจากต้นทางเดียวกัน โดยทำดังนี้

Set-Login: logged-out

หรือเรียกใช้ JavaScript API navigator.login.setStatus('logged-out') จากต้นทางของผู้ให้บริการระบุตัวตน ดังนี้

navigator.login.setStatus('logged-out');

การเรียกเหล่านี้จะบันทึกสถานะการเข้าสู่ระบบของผู้ใช้เป็น logged-out เมื่อสถานะการเข้าสู่ระบบของผู้ใช้คือ logged-out การเรียกใช้ FedCM จะดำเนินการไม่สำเร็จโดยไม่มีการส่งคำขอไปยังปลายทางรายการบัญชีของ IdP

ระบบจะตั้งค่าสถานะ unknown ก่อนที่ IDP จะส่งสัญญาณโดยใช้ Login Status API เราเปิดตัวสถานะนี้เพื่อให้การเปลี่ยนผ่านเป็นไปอย่างราบรื่นยิ่งขึ้น เนื่องจากผู้ใช้อาจลงชื่อเข้าใช้ IdP ไปแล้วเมื่อเราเปิดตัว API นี้ IdP อาจไม่มีเวลาส่งสัญญาณนี้ไปยังเบราว์เซอร์เมื่อมีการเรียกใช้ FedCM เป็นครั้งแรก ในกรณีนี้ เราจะส่งคำขอไปยังปลายทางรายการบัญชีของผู้ให้บริการระบุตัวตน (IdP) และอัปเดตสถานะตามการตอบกลับจากปลายทางรายการบัญชี ดังนี้

  • หากปลายทางแสดงรายการบัญชีที่ใช้งานอยู่ ให้อัปเดตสถานะเป็น logged-in แล้วเปิดกล่องโต้ตอบ FedCM เพื่อแสดงบัญชีเหล่านั้น
  • หากปลายทางไม่แสดงบัญชีใดๆ ให้อัปเดตสถานะเป็น logged-out และดำเนินการเรียกใช้ FedCM ไม่สำเร็จ

จะเกิดอะไรขึ้นหากเซสชันของผู้ใช้หมดอายุ อนุญาตให้ผู้ใช้ลงชื่อเข้าใช้ผ่านขั้นตอนการเข้าสู่ระบบแบบไดนามิก

แม้ว่า IdP จะแจ้งสถานะการเข้าสู่ระบบของผู้ใช้ไปยังเบราว์เซอร์อย่างต่อเนื่อง แต่สถานะอาจไม่ซิงค์กัน เช่น เมื่อเซสชันหมดอายุ เบราว์เซอร์พยายามส่งคําขอที่มีข้อมูลเข้าสู่ระบบไปยังปลายทางรายการบัญชีเมื่อสถานะการเข้าสู่ระบบเป็น logged-in แต่เซิร์ฟเวอร์ไม่แสดงบัญชีใดๆ เนื่องจากเซสชันไม่พร้อมใช้งานแล้ว ในกรณีเช่นนี้ เบราว์เซอร์จะอนุญาตให้ผู้ใช้ลงชื่อเข้าใช้ IdP ผ่านหน้าต่างโต้ตอบแบบไดนามิกได้

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

กล่องโต้ตอบ FedCM ที่แนะนำให้ลงชื่อเข้าใช้ IdP
กล่องโต้ตอบ FedCM ที่แนะนำให้ลงชื่อเข้าใช้ 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

คุณสามารถลองดูลักษณะการทํางานของ Login Status API ในเดโม

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

คุณควรเห็นการเข้าสู่ระบบ IdP ผ่านลักษณะการทํางานของข้อบังคับ

Error API

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

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

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

IdP HTTP API

ในคําตอบ 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;
}

Auto-Selected Flag API

mediation: optional คือลักษณะการสื่อกลางของผู้ใช้เริ่มต้นใน Credential Management API และจะทริกเกอร์การตรวจสอบสิทธิ์อีกครั้งโดยอัตโนมัติเมื่อเป็นไปได้ อย่างไรก็ตาม การตรวจสอบสิทธิ์อีกครั้งโดยอัตโนมัติอาจไม่พร้อมใช้งานเนื่องจากเหตุผลที่เบราว์เซอร์เท่านั้นที่ทราบ เมื่อการตรวจสอบสิทธิ์ไม่พร้อมใช้งาน ระบบอาจแจ้งให้ผู้ใช้ลงชื่อเข้าใช้ด้วยสื่อกลางของผู้ใช้อย่างชัดแจ้ง ซึ่งเป็นขั้นตอนที่มีพร็อพเพอร์ตี้แตกต่างกัน

  • จากมุมมองของผู้เรียก API เมื่อได้รับโทเค็นระบุตัวตน ผู้เรียกจะไม่ทราบว่าเป็นผลลัพธ์ของขั้นตอนการตรวจสอบสิทธิ์ใหม่อัตโนมัติหรือไม่ ซึ่งทำให้ประเมินประสิทธิภาพของ API และปรับปรุง UX ให้เหมาะสมได้ยาก
  • จากมุมมองของผู้ให้บริการระบุตัวตน ผู้ให้บริการไม่สามารถบอกได้ว่ามีการตรวจสอบสิทธิ์ใหม่อัตโนมัติเกิดขึ้นหรือไม่สําหรับการประเมินประสิทธิภาพ นอกจากนี้ การระบุให้ใช้สื่อกลางของผู้ใช้อย่างชัดแจ้งหรือไม่ยังช่วยให้รองรับฟีเจอร์ที่เกี่ยวข้องกับความปลอดภัยได้มากขึ้น เช่น ผู้ใช้บางรายอาจต้องการระดับการรักษาความปลอดภัยที่สูงขึ้น ซึ่งกำหนดให้ต้องมีการสื่อกลางของผู้ใช้อย่างชัดเจนในการตรวจสอบสิทธิ์ หากผู้ให้บริการระบุตัวตนได้รับคําขอโทเค็นโดยไม่มีสื่อกลางดังกล่าว ผู้ให้บริการอาจจัดการคําขอในลักษณะอื่น เช่น ส่งคืนรหัสข้อผิดพลาดเพื่อให้ RP สามารถเรียกใช้ FedCM API อีกครั้งด้วย mediation: required

ดังนั้น การแสดงขั้นตอนการตรวจสอบสิทธิ์ใหม่อัตโนมัติจะเป็นประโยชน์ต่อนักพัฒนาแอป

เมื่อใช้ Flag API ที่เลือกโดยอัตโนมัติ Chrome จะแชร์ว่าได้รับสิทธิ์ที่ชัดเจนจากผู้ใช้หรือไม่โดยการแตะปุ่มดำเนินการต่อในฐานะกับทั้ง IdP และ RP เมื่อใดก็ตามที่มีการตรวจสอบสิทธิ์ใหม่อัตโนมัติหรือมีสื่อกลางที่ชัดเจน การแชร์จะเกิดขึ้นหลังจากที่ผู้ใช้ให้สิทธิ์การสื่อสารกับ IdP/RP แล้วเท่านั้น

การแชร์ 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