การติดตั้งใช้งาน FedCM มีขั้นตอนหลักหลายขั้นตอน สําหรับทั้งผู้ให้บริการข้อมูลประจําตัว (IdP) และฝ่ายที่ต้องอาศัยข้อมูล (RP) โปรดอ่านเอกสารประกอบเพื่อดูวิธีใช้ FedCM ในฝั่ง RP
IdPs ต้องทำตามขั้นตอนต่อไปนี้เพื่อติดตั้งใช้งาน FedCM
- สร้างไฟล์ที่รู้จักกันดี
- สร้างไฟล์การกำหนดค่า
- สร้างปลายทางต่อไปนี้
- แจ้งสถานะการเข้าสู่ระบบของผู้ใช้ให้เบราว์เซอร์ทราบ
สร้างไฟล์ที่รู้จักกันดี
เพื่อป้องกันไม่ให้เครื่องมือติดตามละเมิด API
ต้องแสดงไฟล์ที่รู้จักกันดีจาก /.well-known/web-identity
ของ
eTLD+1 ของ
IdP
ไฟล์ที่รู้จักกันดีอาจมีพร็อพเพอร์ตี้ต่อไปนี้
พร็อพเพอร์ตี้ | ต้องระบุ | คำอธิบาย |
---|---|---|
provider_urls
|
ต้องระบุ | อาร์เรย์ของเส้นทางไฟล์การกำหนดค่า IdP ระบบจะไม่สนใจ (แต่ยังคงต้องระบุ) หากมีการระบุ accounts_endpoint และ login_url |
accounts_endpoint
|
แนะนำ ต้องใช้ login_url |
URL สำหรับปลายทางบัญชี ซึ่งจะช่วยให้รองรับการกำหนดค่าหลายรายการได้ ตราบใดที่ไฟล์การกำหนดค่าแต่ละไฟล์ใช้ URL ของ login_url และ accounts_endpoint เดียวกันหมายเหตุ: ระบบรองรับพารามิเตอร์นี้ตั้งแต่ Chrome 132 |
login_url
|
แนะนำ ต้องใช้ accounts_endpoint |
URL หน้าเข้าสู่ระบบสำหรับให้ผู้ใช้ลงชื่อเข้าใช้ IdP ซึ่งจะช่วยให้รองรับการกำหนดค่าหลายรายการได้ ตราบใดที่ไฟล์กำหนดค่าแต่ละไฟล์ใช้ login_url และ accounts_endpoint เดียวกันหมายเหตุ: ระบบรองรับพารามิเตอร์นี้ตั้งแต่ Chrome 132 ขึ้นไป |
ตัวอย่างเช่น หากมีการแสดงปลายทาง IdP ภายใต้
https://accounts.idp.example/
ปลายทางเหล่านั้นจะต้องแสดงไฟล์ .well-known ที่
https://idp.example/.well-known/web-identity
รวมถึงไฟล์การกำหนดค่า IdP ด้วย ตัวอย่างเนื้อหาไฟล์ที่รู้จักกันดีมีดังนี้
{
"provider_urls": ["https://accounts.idp.example/config.json"]
}
IdP สามารถรองรับไฟล์กำหนดค่าหลายไฟล์สำหรับ IdP ได้โดยการระบุ
accounts_endpoint
และ login_url
ในไฟล์ที่รู้จักกันดี ฟีเจอร์นี้อาจมีประโยชน์ในกรณีต่อไปนี้
- IdP ต้องรองรับการกำหนดค่าการทดสอบและการกำหนดค่าเวอร์ชันที่ใช้งานจริงที่แตกต่างกันหลายรายการ
- IdP ต้องรองรับการกำหนดค่าที่แตกต่างกันในแต่ละภูมิภาค (เช่น
eu-idp.example
และus-idp.example
)
หากต้องการรองรับการกำหนดค่าหลายรายการ (เช่น เพื่อแยกความแตกต่างระหว่างสภาพแวดล้อมการทดสอบ
และสภาพแวดล้อมการผลิต) IdP ต้องระบุ accounts_endpoint
และ
login_url
ดังนี้
{
// This property is required, but will be ignored when IdP supports
// multiple configs (when `accounts_endpoint` and `login_url` are
// specified), as long as `accounts_endpoint` and `login_url` in
// that config file match those in the well-known file.
"provider_urls": [ "https://idp.example/fedcm.json" ],
// Specify accounts_endpoint and login_url properties to support
// multiple config files.
// Note: The accounts_endpoint and login_url must be identical
// across all config files. Otherwise,
// the configurations won't be supported.
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
สร้างไฟล์การกำหนดค่า IdP และปลายทาง
ไฟล์การกำหนดค่า IdP จะแสดงรายการปลายทางที่จำเป็นสำหรับเบราว์เซอร์ IdP
ต้องโฮสต์ไฟล์กำหนดค่าอย่างน้อย 1 ไฟล์ รวมถึงปลายทางและ URL ที่จำเป็น การตอบกลับ JSON ทั้งหมด
ต้องแสดงโดยมีapplication/json
content-type
URL ของไฟล์การกำหนดค่าจะกำหนดโดยค่าที่ระบุในการเรียกใช้ navigator.credentials.get()
ที่ดำเนินการใน RP
RP จะส่ง URL ของไฟล์การกำหนดค่าสำหรับผู้ให้บริการข้อมูลประจำตัวทุกราย
// Executed on RP's side:
try {
const credential = await navigator.credentials.get({
identity: {
providers: [
{
// To allow users to sign in with the IdP1 using FedCM, RP specifies the IdP's config file URL:
configUrl: 'https://idp1.example/foo.json', // first IdP
clientId: '123',
},
// To allow users to sign in with the IdP2 using FedCM, RP specifies the IdP's config file URL.
// Note that multiple IdPs in a single get() are supported from Chrome 136.
{
configUrl: 'https://idp2.example/bar.json', // second IdP
clientId: '456',
},
],
},
});
const token = credential.token;
// Get the current IdP's configURL to identify which provider the user is signed in with
const currentIdpConfigUrl = credential.configURL;
if (currentIdpConfigUrl === 'https://idp1.example/foo.json') {
// handle the case where the user signed in with idp1
} else if (currentIdpConfigUrl === 'https://idp2.example/bar.json') {
// handle the case where the user signed in with idp2
}
} catch (error) {
// handle error
}
เบราว์เซอร์จะดึงข้อมูลไฟล์กำหนดค่าด้วยคำขอ GET
โดยไม่มีส่วนหัว Origin
หรือส่วนหัว Referer
คำขอไม่มีคุกกี้และไม่
ติดตามการเปลี่ยนเส้นทาง ซึ่งจะป้องกันไม่ให้ IdP ทราบว่าใครเป็นผู้ส่งคำขอและ RP ใดพยายามเชื่อมต่อ เช่น
GET /config.json HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity
IdP ต้องใช้ปลายทางการกำหนดค่าที่ตอบกลับด้วย JSON JSON มีพร็อพเพอร์ตี้ต่อไปนี้
พร็อพเพอร์ตี้ | คำอธิบาย |
---|---|
accounts_endpoint (ต้องระบุ) |
URL สำหรับปลายทางบัญชี |
account_label (ไม่บังคับ)
|
สตริงป้ายกำกับบัญชีที่กำหนดเอง ซึ่งกำหนดว่าควรแสดงบัญชีใดเมื่อใช้ไฟล์การกำหนดค่านี้ เช่น "account_label": "developer"
IdP สามารถใช้การติดป้ายกำกับบัญชีที่กำหนดเองได้ดังนี้
ตัวอย่างเช่น IdP จะใช้ "https://idp.example/developer-config.json" ไฟล์กำหนดค่าที่มี"account_label": "developer" ที่ระบุ นอกจากนี้ IdP ยังทำเครื่องหมายบัญชีบางบัญชีด้วยป้ายกำกับ "developer" โดยใช้พารามิเตอร์ label_hints ในปลายทางของบัญชี เมื่อ RP เรียกใช้ navigator.credentials.get() โดยระบุไฟล์กำหนดค่า "https://idp.example/developer-config.json" ระบบจะแสดงผลเฉพาะบัญชีที่มีป้ายกำกับ "developer" หมายเหตุ: ป้ายกำกับบัญชีที่กำหนดเองรองรับตั้งแต่ Chrome 132 |
supports_use_other_account (ไม่บังคับ) |
บูลีนที่ระบุว่าผู้ใช้จะลงชื่อเข้าใช้ด้วยบัญชีอื่นที่แตกต่างจากบัญชีที่เข้าสู่ระบบอยู่ในปัจจุบันได้หรือไม่ (หาก IdP รองรับหลายบัญชี) ซึ่งจะมีผลกับโหมดทำงานเท่านั้น |
client_metadata_endpoint (ไม่บังคับ) |
URL สำหรับปลายทางข้อมูลเมตาของไคลเอ็นต์ |
id_assertion_endpoint (ต้องระบุ) |
URL สำหรับปลายทางการยืนยันรหัส |
disconnect (ไม่บังคับ) |
URL สำหรับปลายทางการยกเลิกการเชื่อมต่อ |
login_url (ต้องระบุ) |
URL หน้าเข้าสู่ระบบสำหรับให้ผู้ใช้ลงชื่อเข้าใช้ IdP |
branding (ไม่บังคับ) |
ออบเจ็กต์ที่มีตัวเลือกการสร้างแบรนด์ต่างๆ |
branding.background_color (ไม่บังคับ) |
ตัวเลือกการสร้างแบรนด์ที่ตั้งค่าสีพื้นหลังของปุ่ม "ดำเนินการต่อในชื่อ..." ใช้ไวยากรณ์ CSS ที่เกี่ยวข้อง ได้แก่
hex-color
hsl()
rgb() หรือ
named-color |
branding.color (ไม่บังคับ) |
ตัวเลือกการสร้างแบรนด์ที่กำหนดสีข้อความของปุ่ม "ดำเนินการต่อในชื่อ..." ใช้ไวยากรณ์ CSS ที่เกี่ยวข้อง ได้แก่
hex-color
hsl()
rgb() หรือ
named-color |
branding.icons (ไม่บังคับ) |
อาร์เรย์ของออบเจ็กต์ไอคอน ไอคอนเหล่านี้จะแสดงในกล่องโต้ตอบการลงชื่อเข้าใช้ ออบเจ็กต์ไอคอนมีพารามิเตอร์ 2 รายการ ดังนี้
|
ต่อไปนี้คือตัวอย่างเนื้อหาการตอบกลับจาก IdP
{
"accounts_endpoint": "/accounts.example",
"client_metadata_endpoint": "/client_metadata.example",
"id_assertion_endpoint": "/assertion.example",
"disconnect_endpoint": "/disconnect.example",
"login_url": "/login",
// When RPs use this config file, only those accounts will be
//returned that include `developer` label in the accounts endpoint.
"account_label": "developer",
"supports_use_other_account": true,
"branding": {
"background_color": "green",
"color": "#FFEEAA",
"icons": [{
"url": "https://idp.example/icon.ico",
"size": 25
}]
}
}
เมื่อเบราว์เซอร์ดึงข้อมูลไฟล์กำหนดค่าแล้ว เบราว์เซอร์จะส่งคำขอที่ตามมาไปยัง ปลายทาง IdP

ใช้บัญชีอื่น
ผู้ใช้สามารถเปลี่ยนไปใช้บัญชีอื่นที่ไม่ใช่บัญชีที่กำลัง เข้าสู่ระบบได้ หาก IdP รองรับหลายบัญชีหรือการแทนที่บัญชีที่มีอยู่
หากต้องการให้ผู้ใช้เลือกบัญชีอื่นได้ IdP ต้องระบุฟีเจอร์นี้ ในไฟล์กำหนดค่า
{
"accounts_endpoint" : "/accounts.example",
"supports_use_other_account": true
}
ปลายทางของบัญชี
ปลายทางบัญชีของ IdP จะแสดงรายการบัญชีที่ผู้ใช้ลงชื่อเข้าใช้ใน IdP หาก IdP รองรับหลายบัญชี ปลายทางนี้จะแสดงบัญชีที่ลงชื่อเข้าใช้ทั้งหมด
เบราว์เซอร์จะส่งคำขอ GET
พร้อมคุกกี้ที่มี SameSite=None
แต่ไม่มีพารามิเตอร์ client_id
ส่วนหัว Origin
หรือส่วนหัว Referer
ซึ่งจะ
ป้องกันไม่ให้ IdP ทราบว่า RP ใดที่ผู้ใช้พยายามลงชื่อเข้าใช้
ได้อย่างมีประสิทธิภาพ เช่น
GET /accounts.example HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
เมื่อได้รับคำขอ เซิร์ฟเวอร์ควรดำเนินการดังนี้
- ตรวจสอบว่าคำขอมีส่วนหัว
Sec-Fetch-Dest: webidentity
HTTP - จับคู่คุกกี้เซสชันกับรหัสของบัญชีที่ลงชื่อเข้าใช้แล้ว
- ตอบกลับพร้อมรายการบัญชี
เบราว์เซอร์คาดหวังว่าจะได้รับการตอบกลับ JSON ที่มีพร็อพเพอร์ตี้ accounts
พร้อมอาร์เรย์ข้อมูลบัญชีที่มีพร็อพเพอร์ตี้ต่อไปนี้
พร็อพเพอร์ตี้ | คำอธิบาย |
---|---|
id (ต้องระบุ) |
รหัสที่ไม่ซ้ำกันของผู้ใช้ |
name |
ชื่อเต็มของผู้ใช้ตามภาษาและค่ากำหนดของผู้ใช้ หมายเหตุ: ตั้งแต่ Chrome 141 เป็นต้นไป จะต้องมีพารามิเตอร์ name , email , username หรือ tel อย่างน้อย 1 รายการ ใน Chrome เวอร์ชันก่อนหน้า คุณต้องระบุทั้ง name และ email
|
username |
ชื่อผู้ใช้ที่ผู้ใช้เลือก หมายเหตุ: ตั้งแต่ Chrome 141 เป็นต้นไป จะต้องมีพารามิเตอร์ name , email , username หรือ tel อย่างน้อย 1 รายการ
|
email |
อีเมลของผู้ใช้ หมายเหตุ: ตั้งแต่ Chrome 141 เป็นต้นไป จะต้องมีพารามิเตอร์ name , email , username หรือ tel อย่างน้อย 1 รายการ ใน Chrome เวอร์ชันก่อนหน้า คุณต้องระบุทั้ง name และ email
|
tel |
หมายเลขโทรศัพท์ของผู้ใช้ หมายเหตุ: ตั้งแต่ Chrome 141 เป็นต้นไป จะต้องมีพารามิเตอร์ name , email , username หรือ tel อย่างน้อย 1 รายการ
|
picture (ไม่บังคับ) |
URL ของรูปโปรไฟล์ผู้ใช้ |
given_name (ไม่บังคับ) |
ชื่อของผู้ใช้ |
approved_clients (ไม่บังคับ) |
อาร์เรย์ของรหัสไคลเอ็นต์ RP ที่ผู้ใช้ลงทะเบียนไว้ |
login_hints (ไม่บังคับ) |
อาร์เรย์ของประเภทตัวกรองทั้งหมดที่ IdP รองรับเพื่อระบุ
บัญชี RP สามารถเรียกใช้ navigator.credentials.get()
ด้วยพร็อพเพอร์ตี้ loginHint เพื่อ
แสดงบัญชีที่ระบุอย่างเลือกสรร |
domain_hints (ไม่บังคับ) |
อาร์เรย์ของโดเมนทั้งหมดที่บัญชีเชื่อมโยงอยู่ RP สามารถ
เรียกใช้ navigator.credentials.get() โดยมีพร็อพเพอร์ตี้
domainHint เพื่อกรองบัญชีได้ |
label_hints (ไม่บังคับ)
|
อาร์เรย์ของป้ายกำกับบัญชีที่กำหนดเองแบบสตริงที่บัญชีเชื่อมโยงอยู่ IdP สามารถใช้การติดป้ายกำกับบัญชีที่กำหนดเองได้ดังนี้
ตัวอย่างเช่น IdP จะใช้ https://idp.example/developer-config.json ไฟล์กำหนดค่าที่มี"account_label": "developer" ที่ระบุ นอกจากนี้ IdP ยังทำเครื่องหมายบัญชีบางบัญชีด้วยป้ายกำกับ "developer" โดยใช้พารามิเตอร์ label_hints ใน ปลายทางของบัญชี เมื่อ RP เรียกใช้ navigator.credentials.get() โดยระบุไฟล์กำหนดค่า https://idp.example/developer-config.json ระบบจะแสดงเฉพาะบัญชีที่มีป้ายกำกับ "developer" ป้ายกำกับบัญชีที่กำหนดเองแตกต่างจากคำแนะนำในการเข้าสู่ระบบและคำแนะนำโดเมนในลักษณะที่เซิร์ฟเวอร์ IdP เป็นผู้ดูแลรักษาป้ายกำกับบัญชีที่กำหนดเองทั้งหมด และ RP จะระบุเฉพาะไฟล์การกำหนดค่าที่จะใช้ หมายเหตุ: ป้ายกำกับบัญชีที่กำหนดเองรองรับตั้งแต่ Chrome 132 |
ตัวอย่างเนื้อหาการตอบกลับ
{
"accounts": [{
"id": "1234",
"given_name": "John",
"name": "John Doe",
"email": "john_doe@idp.example",
"picture": "https://idp.example/profile/123",
// Ids of those RPs where this account can be used
"approved_clients": ["123", "456", "789"],
// This account has 'login_hints`. When an RP calls `navigator.credentials.get()`
// with a `loginHint` value specified, for example, `exampleHint`, only those
// accounts will be shown to the user whose 'login_hints' array contains the `exampleHint`.
"login_hints": ["demo1", "exampleHint"],
// This account is labelled. IdP can implement a specific config file for a
// label, for example, `https://idp.example/developer-config.json`. Like that
// RPs can filter out accounts by calling `navigator.credentials.get()` with
// `https://idp.example/developer-config.json` config file.
"label_hints": ["enterprise", "developer"]
}, {
"id": "5678",
"given_name": "Johnny",
"name": "Johnny",
"email": "johnny@idp.example",
"picture": "https://idp.example/profile/456",
"approved_clients": ["abc", "def", "ghi"],
"login_hints": ["demo2"],
"domain_hints": ["@domain.example"]
}]
}
หากผู้ใช้ไม่ได้ลงชื่อเข้าใช้ ให้ตอบกลับด้วย HTTP 401
(ไม่ได้รับอนุญาต)
เบราว์เซอร์จะใช้รายการบัญชีที่ส่งคืนและ RP จะใช้ไม่ได้
ปลายทางการยืนยันตัวตน
ปลายทางการยืนยันรหัสของ IdP จะแสดงการยืนยันสำหรับผู้ใช้ที่ลงชื่อเข้าใช้
เมื่อผู้ใช้ลงชื่อเข้าใช้เว็บไซต์ RP โดยใช้ navigator.credentials.get()
call เบราว์เซอร์จะส่งคำขอ POST
พร้อมคุกกี้ที่มี SameSite=None
และประเภทเนื้อหา application/x-www-form-urlencoded
ไปยังปลายทางนี้พร้อมข้อมูลต่อไปนี้
พร็อพเพอร์ตี้ | คำอธิบาย |
---|---|
client_id (ต้องระบุ) |
ตัวระบุไคลเอ็นต์ของ RP |
account_id (ต้องระบุ) |
รหัสที่ไม่ซ้ำกันของผู้ใช้ที่ลงชื่อเข้าใช้ |
disclosure_text_shown |
แสดงผลเป็นสตริงของ "true" หรือ "false" (ไม่ใช่บูลีน) ผลลัพธ์จะเป็น "false" ในกรณีต่อไปนี้
|
disclosure_shown_for |
แสดงรายการช่องที่เบราว์เซอร์แสดงต่อผู้ใช้ในข้อความการเปิดเผยข้อมูลเพื่อแจ้งให้ผู้ใช้ทราบว่า RP กำลังขอข้อมูลใดจาก IdP |
is_auto_selected |
หากมีการตรวจสอบสิทธิ์อีกครั้งโดยอัตโนมัติใน RP is_auto_selected จะระบุ "true" หรือ "false" ซึ่งจะเป็นประโยชน์ในการรองรับฟีเจอร์ที่เกี่ยวข้องกับการรักษาความปลอดภัยเพิ่มเติม ตัวอย่างเช่น ผู้ใช้บางรายอาจต้องการระดับความปลอดภัยที่สูงขึ้น ซึ่งต้องมีการแทรกแซงจากผู้ใช้โดยชัดแจ้งในการตรวจสอบสิทธิ์ หาก IdP ได้รับคำขอโทเค็นโดยไม่มีการไกล่เกลี่ยดังกล่าว IdP อาจจัดการคำขอแตกต่างออกไป เช่น แสดงรหัสข้อผิดพลาดเพื่อให้ RP เรียกใช้ FedCM API อีกครั้งด้วย mediation: required |
fields (ไม่บังคับ)
|
อาร์เรย์ของสตริงที่ระบุข้อมูลผู้ใช้ที่ RP ขอให้ IdP แชร์ คุณระบุฟิลด์ต่อไปนี้หรือไม่ก็ได้
fields , disclosure_text_shown และ disclosure_shown_for ที่แสดงฟิลด์ที่ระบุในคำขอ POST ดังในตัวอย่างต่อไปนี้หมายเหตุ: Chrome 132 ขึ้นไปรองรับ Fields API ฟิลด์ `"username"` และ `"tel"` รองรับตั้งแต่ Chrome 141 |
params (ไม่บังคับ)
|
ออบเจ็กต์ JSON ที่ถูกต้องซึ่งอนุญาตให้ระบุพารามิเตอร์คู่คีย์-ค่าที่กำหนดเองเพิ่มเติม เช่น
params เป็น JSON แล้วเข้ารหัสเปอร์เซ็นต์หมายเหตุ: Chrome 132 ขึ้นไปรองรับ API พารามิเตอร์ |
ตัวอย่างส่วนหัว HTTP
POST /assertion.example HTTP/1.1
Host: accounts.idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
// disclosure_text_shown is set to 'false', as the 'name' field value is missing in 'fields' array
// params value is serialized to JSON and then percent-encoded.
account_id=123&client_id=client1234&disclosure_text_shown=false&is_auto_selected=true¶ms=%22%7B%5C%22nonce%5C%22%3A%5C%22nonce-value%5C%22%7D%22.%0D%0A4&fields=email,picture&disclosure_shown_for=email,picture
เมื่อได้รับคำขอ เซิร์ฟเวอร์ควรดำเนินการดังนี้
- ตอบสนองต่อคำขอด้วย CORS (การแชร์ทรัพยากรข้ามโดเมน)
- ตรวจสอบว่าคำขอมีส่วนหัว
Sec-Fetch-Dest: webidentity
HTTP - จับคู่ส่วนหัว
Origin
กับต้นทาง RP ที่กำหนดโดยclient_id
ปฏิเสธหากไม่ตรงกัน - จับคู่
account_id
กับรหัสของบัญชีที่ลงชื่อเข้าใช้แล้ว ปฏิเสธ หากไม่ตรงกัน - ตอบกลับด้วยโทเค็น หากคำขอถูกปฏิเสธ ให้ตอบกลับด้วยการตอบกลับ ข้อผิดพลาด
IdP สามารถกำหนดวิธีออกโทเค็นได้ โดยทั่วไปแล้ว ระบบจะลงนามด้วย ข้อมูลต่างๆ เช่น รหัสบัญชี รหัสไคลเอ็นต์ ต้นทางของผู้ออก และ Nonce เพื่อให้ RP ยืนยันได้ว่าโทเค็นเป็นของแท้
เบราว์เซอร์คาดหวังการตอบกลับ JSON ที่มีพร็อพเพอร์ตี้ต่อไปนี้
พร็อพเพอร์ตี้ | คำอธิบาย |
---|---|
token |
โทเค็นคือสตริงที่มีการอ้างสิทธิ์เกี่ยวกับการตรวจสอบสิทธิ์ |
continue_on |
URL เปลี่ยนเส้นทางที่เปิดใช้ขั้นตอนการลงชื่อเข้าใช้แบบหลายขั้นตอน |
เบราว์เซอร์จะส่งโทเค็นที่ส่งคืนไปยัง RP เพื่อให้ RP สามารถ ตรวจสอบการตรวจสอบสิทธิ์ได้
{
// IdP can respond with a token to authenticate the user
"token": "***********"
}
ดำเนินการต่อในฟีเจอร์
IdP สามารถระบุ URL การเปลี่ยนเส้นทางในการตอบกลับปลายทาง การยืนยันรหัสเพื่อเปิดใช้ขั้นตอนการลงชื่อเข้าใช้แบบหลายขั้นตอน ซึ่งจะมีประโยชน์ในกรณีที่ IdP ต้องขอข้อมูลเพิ่มเติมหรือ สิทธิ์ เช่น
- สิทธิ์เข้าถึงทรัพยากรฝั่งเซิร์ฟเวอร์ของผู้ใช้
- การยืนยันว่าข้อมูลติดต่อเป็นข้อมูลล่าสุด
- การควบคุมโดยผู้ปกครอง
ปลายทางการยืนยันรหัสสามารถแสดงพร็อพเพอร์ตี้ continue_on
ซึ่งมี
เส้นทางแบบสัมบูรณ์หรือแบบสัมพัทธ์ไปยังปลายทางการยืนยันรหัส
{
// In the id_assertion_endpoint, instead of returning a typical
// "token" response, the IdP decides that it needs the user to
// continue on a popup window:
"continue_on": "https://idp.example/continue_on_url"
}
หากการตอบกลับมีพารามิเตอร์ continue_on
ระบบจะเปิดหน้าต่างป๊อปอัปใหม่
และนำผู้ใช้ไปยังเส้นทางที่ระบุ หลังจากที่ผู้ใช้โต้ตอบกับหน้า continue_on
แล้ว IdP ควรเรียกใช้ IdentityProvider.resolve()
โดยส่งโทเค็นเป็นอาร์กิวเมนต์เพื่อให้สัญญาจากการเรียกใช้ navigator.credentials.get()
เดิมได้รับการแก้ไข
document.getElementById('example-button').addEventListener('click', async () => {
let accessToken = await fetch('/generate_access_token.cgi');
// Closes the window and resolves the promise (that is still hanging
// in the relying party's renderer) with the value that is passed.
IdentityProvider.resolve(accessToken);
});
จากนั้นเบราว์เซอร์จะปิดป๊อปอัปโดยอัตโนมัติและส่งโทเค็นกลับไปยัง
ผู้เรียก API IdentityProvider.resolve()
การเรียกใช้แบบครั้งเดียวเป็นวิธีเดียวที่หน้าต่างหลัก (RP) และหน้าต่างป๊อปอัป (IdP) จะสื่อสารกันได้
หากผู้ใช้ปฏิเสธคำขอ IdP จะปิดหน้าต่างได้โดยเรียกใช้
IdentityProvider.close()
IdentityProvider.close();
Continuation API ต้องมีการโต้ตอบจากผู้ใช้ที่ชัดเจน (การคลิก) จึงจะทำงานได้ Continuation API ทำงานร่วมกับโหมดสื่อกลาง ต่างๆ ดังนี้
- ใน
passive
โหมดmediation: 'optional'
(ค่าเริ่มต้น): Continuation API จะทํางานได้ก็ต่อเมื่อ ผู้ใช้ทําท่าทาง เช่น คลิกปุ่มในหน้าเว็บหรือใน UI ของ FedCM เมื่อระบบทริกเกอร์การตรวจสอบสิทธิ์อีกครั้งโดยอัตโนมัติโดยไม่มีท่าทางของผู้ใช้ ระบบจะไม่เปิดหน้าต่างป๊อปอัปและจะปฏิเสธสัญญาmediation: 'required'
: ขอให้ผู้ใช้โต้ตอบเสมอ ดังนั้น Continuation API จึงใช้งานได้เสมอ
- ในโหมดใช้งาน ให้ทำดังนี้
- ต้องเปิดใช้งานผู้ใช้เสมอ Continuation API จะเข้ากันได้เสมอ
หากผู้ใช้เปลี่ยนบัญชีในป๊อปอัปด้วยเหตุผลบางประการ (เช่น IdP มีฟังก์ชัน "ใช้บัญชีอื่น" หรือในกรณีการมอบสิทธิ์) การเรียก resolve จะมีอาร์กิวเมนต์ที่ 2 ที่ไม่บังคับซึ่งอนุญาตให้ใช้สิ่งต่อไปนี้
IdentityProvider.resolve(token, {accountId: '1234');
แสดงการตอบกลับข้อผิดพลาด
id_assertion_endpoint
ยังแสดงผลการตอบกลับ "ข้อผิดพลาด"
ซึ่งมี 2 ฟิลด์ที่ไม่บังคับได้ด้วย ดังนี้
code
: IdP สามารถเลือกข้อผิดพลาดที่ทราบจากรายการข้อผิดพลาดที่ระบุของ OAuth 2.0 (invalid_request
,unauthorized_client
,access_denied
,server_error
และtemporarily_unavailable
) หรือใช้สตริงใดก็ได้ หากเป็นกรณีหลัง Chrome จะแสดง UI ข้อผิดพลาดพร้อมข้อความแสดงข้อผิดพลาดทั่วไปและส่งรหัส ไปยัง RPurl
: ระบุหน้าเว็บที่มนุษย์อ่านได้ซึ่งมีข้อมูลเกี่ยวกับข้อผิดพลาดเพื่อให้ข้อมูลเพิ่มเติมเกี่ยวกับข้อผิดพลาดแก่ผู้ใช้ ฟิลด์นี้มีประโยชน์ต่อผู้ใช้เนื่องจากเบราว์เซอร์ไม่สามารถแสดงข้อความแสดงข้อผิดพลาดที่สมบูรณ์ใน UI ในตัวได้ เช่น ลิงก์สำหรับขั้นตอนถัดไปหรือข้อมูลติดต่อของฝ่ายบริการลูกค้า หากผู้ใช้ต้องการดูรายละเอียดข้อผิดพลาดเพิ่มเติม และวิธีแก้ไข ผู้ใช้สามารถไปที่หน้าที่ระบุจาก UI ของเบราว์เซอร์ เพื่อดูรายละเอียดเพิ่มเติมได้ URL ต้องเป็นแบบเว็บไซต์เดียวกันกับ IdPconfigURL
// id_assertion_endpoint response
{
"error" : {
"code": "access_denied",
"url" : "https://idp.example/error?type=access_denied"
}
}
ป้ายกำกับบัญชีที่กำหนดเอง
ป้ายกำกับบัญชีที่กำหนดเองช่วยให้ IdP สามารถใส่คำอธิบายประกอบในบัญชีผู้ใช้ด้วยป้ายกำกับ และ RP สามารถเลือกที่จะดึงข้อมูลเฉพาะบัญชีที่มีป้ายกำกับที่เฉพาะเจาะจงได้โดยการระบุ configURL
สำหรับป้ายกำกับที่เฉพาะเจาะจงนั้น ซึ่งอาจมีประโยชน์เมื่อ RP ต้องการกรองบัญชีตามเกณฑ์ที่เฉพาะเจาะจง เช่น เพื่อแสดงเฉพาะบัญชีที่เฉพาะเจาะจงตามบทบาท เช่น "developer"
หรือ "hr"
คุณสามารถกรองในลักษณะเดียวกันได้โดยใช้ฟีเจอร์คำแนะนำโดเมนและ
คำแนะนำในการเข้าสู่ระบบ โดยระบุฟีเจอร์ดังกล่าวใน
การเรียกใช้ navigator.credentials.get()
อย่างไรก็ตาม ป้ายกำกับบัญชีที่กำหนดเองสามารถกรอง
ผู้ใช้ได้โดยการระบุไฟล์กำหนดค่า ซึ่งมีประโยชน์อย่างยิ่งเมื่อใช้ configURL หลายรายการ ป้ายกำกับบัญชีที่กำหนดเองยังแตกต่างกันตรงที่มาจากเซิร์ฟเวอร์ IdP ไม่ใช่จาก RP เหมือนกับคำแนะนำในการเข้าสู่ระบบหรือโดเมน
พิจารณา IdP ที่ต้องการแยกความแตกต่างระหว่างบัญชี "developer"
กับ "hr"
หากต้องการดำเนินการนี้ IdP ต้องรองรับ ConfigURL 2 รายการสำหรับ
"developer"
และ "hr"
ตามลำดับ
- ไฟล์การกำหนดค่าของนักพัฒนาซอฟต์แวร์
https://idp.example/developer/fedcm.json
มีป้ายกำกับ"developer"
และไฟล์การกำหนดค่าขององค์กรhttps://idp.example/hr/fedcm.json
มีป้ายกำกับ"hr"
ดังนี้
// The developer config file at `https://idp.example/developer/fedcm.json`
{
"accounts_endpoint": "https://idp.example/accounts",
"client_metadata_endpoint": "/client_metadata",
"login_url": "https://idp.example/login",
"id_assertion_endpoint": "/assertion",
"account_label": "developer"
}
// The hr config file at `https://idp.example/hr/fedcm.json`
{
"accounts_endpoint": "https://idp.example/accounts",
"client_metadata_endpoint": "/client_metadata",
"login_url": "https://idp.example/login",
"id_assertion_endpoint": "/assertion",
"account_label": "hr"
}
- เมื่อตั้งค่าดังกล่าว ไฟล์ที่รู้จักกันดีควรมี
accounts_endpoint
และlogin_url
เพื่ออนุญาตให้มี configURL หลายรายการ
{
"provider_urls": [ "https://idp.example/fedcm.json" ],
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
- ปลายทางบัญชี IdP ทั่วไป (ในตัวอย่างนี้คือ
https://idp.example/accounts
) จะแสดงรายการบัญชีที่มีพร็อพเพอร์ตี้label_hints
พร้อมป้ายกำกับที่กำหนดในอาร์เรย์สำหรับแต่ละบัญชี
{
"accounts": [{
"id": "123",
"given_name": "John",
"name": "John Doe",
"email": "john_doe@idp.example",
"picture": "https://idp.example/profile/123",
"label_hints": ["developer"]
}], [{
"id": "4567",
"given_name": "Jane",
"name": "Jane Doe",
"email": "jane_doe@idp.example",
"picture": "https://idp.example/profile/4567",
"label_hints": ["hr"]
}]
}
เมื่อ RP ต้องการอนุญาตให้"hr"
ผู้ใช้ลงชื่อเข้าใช้ RP จะระบุ
configURL https://idp.example/hr/fedcm.json
ในการเรียกใช้
navigator.credentials.get()
ได้
let { token } = await navigator.credentials.get({
identity: {
providers: [{
clientId: '1234',
nonce: '234234',
configURL: 'https://idp.example/hr/fedcm.json',
},
}
});
ดังนั้น ผู้ใช้จะลงชื่อเข้าใช้ได้โดยใช้รหัสบัญชีของ 4567
เท่านั้น
เบราว์เซอร์จะซ่อนรหัสบัญชีของ 123
โดยไม่แจ้งให้ทราบ เพื่อไม่ให้ผู้ใช้
ได้รับบัญชีที่ IdP ไม่รองรับในเว็บไซต์นี้
ข้อควรพิจารณาเพิ่มเติม
- ป้ายกำกับเป็นสตริง หากอาร์เรย์
label_hints
หรือฟิลด์account_label
ใช้ค่าที่ไม่ใช่สตริง ระบบจะไม่สนใจค่าดังกล่าว - หากไม่ได้ระบุป้ายกำกับใน
configURL
ระบบจะแสดงบัญชีทั้งหมด ในเครื่องมือเลือกบัญชี FedCM - หากไม่ได้ระบุป้ายกำกับสำหรับบัญชี บัญชีนี้จะแสดงในตัวเลือกบัญชีก็ต่อเมื่อ
configURL
ไม่ได้ระบุป้ายกำกับด้วย - หากไม่มีบัญชีใดตรงกับป้ายกำกับที่ขอในโหมดพาสซีฟ (คล้ายกับฟีเจอร์คำแนะนำโดเมน) กล่องโต้ตอบ FedCM จะแสดงข้อความแจ้งให้เข้าสู่ระบบ ซึ่งจะช่วยให้ผู้ใช้ลงชื่อเข้าใช้บัญชี IdP ได้ สำหรับโหมดที่ใช้งานอยู่ ระบบจะเปิดหน้าต่างป๊อปอัปการเข้าสู่ระบบโดยตรง
ยกเลิกการเชื่อมต่ออุปกรณ์ปลายทาง
เมื่อเรียกใช้ IdentityCredential.disconnect()
เบราว์เซอร์จะส่งคำขอข้ามต้นทาง
POST
พร้อมคุกกี้ที่มี SameSite=None
และประเภทเนื้อหา
application/x-www-form-urlencoded
ไปยังปลายทางการยกเลิกการเชื่อมต่อนี้พร้อมข้อมูลต่อไปนี้
พร็อพเพอร์ตี้ | คำอธิบาย |
---|---|
account_hint |
คำใบ้สำหรับบัญชี IdP |
client_id |
ตัวระบุไคลเอ็นต์ของ RP |
POST /disconnect.example HTTP/1.1
Host: idp.example
Origin: rp.example
Content-Type: application/x-www-form-urlencoded
Cookie: 0x123
Sec-Fetch-Dest: webidentity
account_hint=account456&client_id=rp123
เมื่อได้รับคำขอ เซิร์ฟเวอร์ควรดำเนินการดังนี้
- ตอบสนองต่อคำขอด้วย CORS (การแชร์ทรัพยากรข้ามโดเมน)
- ตรวจสอบว่าคำขอมีส่วนหัว
Sec-Fetch-Dest: webidentity
HTTP - จับคู่ส่วนหัว
Origin
กับต้นทาง RP ที่กำหนดโดยclient_id
ปฏิเสธหากไม่ตรงกัน - จับคู่
account_hint
กับรหัสของบัญชีที่ลงชื่อเข้าใช้แล้ว - ยกเลิกการเชื่อมต่อบัญชีผู้ใช้จาก RP
- ตอบกลับเบราว์เซอร์ด้วยข้อมูลบัญชีผู้ใช้ที่ระบุใน รูปแบบ JSON
เพย์โหลด JSON ของการตอบกลับตัวอย่างมีลักษณะดังนี้
{
"account_id": "account456"
}
แต่หาก IdP ต้องการให้เบราว์เซอร์ยกเลิกการเชื่อมต่อบัญชีทั้งหมดที่เชื่อมโยงกับ RP ให้ส่งสตริงที่ไม่ตรงกับรหัสบัญชีใดๆ เช่น "*"
ปลายทางข้อมูลเมตาของไคลเอ็นต์
ปลายทางข้อมูลเมตาของไคลเอ็นต์ IdP จะแสดงข้อมูลเมตาของ Relying Party เช่น นโยบายความเป็นส่วนตัว ข้อกำหนดในการให้บริการ และไอคอนโลโก้ของ RP RP ควรระบุลิงก์ไปยังนโยบายความเป็นส่วนตัวและข้อกำหนดในการให้บริการของตนให้ IdP ทราบล่วงหน้า ลิงก์เหล่านี้จะแสดงในกล่องโต้ตอบการลงชื่อเข้าใช้เมื่อผู้ใช้ยังไม่ได้ลงทะเบียนใน RP ด้วย IdP
เบราว์เซอร์จะส่งคำขอ GET
โดยใช้ client_id
navigator.credentials.get
โดยไม่มีคุกกี้ เช่น
GET /client_metadata.example?client_id=1234 HTTP/1.1
Host: accounts.idp.example
Origin: https://rp.example/
Accept: application/json
Sec-Fetch-Dest: webidentity
เมื่อได้รับคำขอ เซิร์ฟเวอร์ควรดำเนินการดังนี้
- กำหนด RP สำหรับ
client_id
- ตอบกลับด้วยข้อมูลเมตาของไคลเอ็นต์
พร็อพเพอร์ตี้สำหรับปลายทางข้อมูลเมตาของไคลเอ็นต์มีดังนี้
พร็อพเพอร์ตี้ | คำอธิบาย |
---|---|
privacy_policy_url (ไม่บังคับ) |
URL ของนโยบายความเป็นส่วนตัวของ RP |
terms_of_service_url (ไม่บังคับ) |
URL ของข้อกำหนดในการให้บริการของ RP |
icons (ไม่บังคับ) |
อาร์เรย์ของออบเจ็กต์ เช่น [{ "url": "https://rp.example/rp-icon.ico", "size": 40}] |
เบราว์เซอร์คาดหวังว่าจะได้รับการตอบกลับแบบ JSON จากปลายทาง
{
"privacy_policy_url": "https://rp.example/privacy_policy.html",
"terms_of_service_url": "https://rp.example/terms_of_service.html",
"icons": [{
"url": "https://rp.example/rp-icon.ico",
"size": 40
}]
}
เบราว์เซอร์จะใช้ข้อมูลเมตาของไคลเอ็นต์ที่ส่งคืน และ RP จะใช้ข้อมูลเมตาดังกล่าวไม่ได้
URL เข้าสู่ระบบ
ระบบใช้ปลายทางนี้เพื่อให้ผู้ใช้ลงชื่อเข้าใช้ IdP ได้
เมื่อใช้ Login Status API IdP ต้องแจ้งสถานะการเข้าสู่ระบบของผู้ใช้ให้เบราว์เซอร์ทราบ
อย่างไรก็ตาม สถานะอาจไม่ซิงค์ เช่น
เมื่อเซสชันหมดอายุ ในสถานการณ์เช่นนี้ เบราว์เซอร์จะอนุญาตให้ผู้ใช้ลงชื่อเข้าใช้ IdP ผ่าน URL ของหน้าเข้าสู่ระบบที่ระบุไว้ในไฟล์กำหนดค่า IdP ของ login_url
ได้แบบไดนามิก
กล่องโต้ตอบ FedCM จะแสดงข้อความที่แนะนำให้ลงชื่อเข้าใช้ ดังที่แสดงใน รูปภาพต่อไปนี้

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

กล่องโต้ตอบคือหน้าต่างเบราว์เซอร์ปกติที่มีคุกกี้ของบุคคลที่หนึ่ง ไม่ว่าจะเกิดอะไรขึ้นภายในกล่องโต้ตอบก็ขึ้นอยู่กับ IdP และไม่มีแฮนเดิลหน้าต่างที่จะส่งคำขอการสื่อสารข้ามต้นทางไปยังหน้า RP หลังจากผู้ใช้ ลงชื่อเข้าใช้แล้ว IdP ควรทำดังนี้
- ส่งส่วนหัว
Set-Login: logged-in
หรือเรียกใช้ APInavigator.login.setStatus("logged-in")
เพื่อแจ้งให้เบราว์เซอร์ทราบว่าผู้ใช้ได้ลงชื่อเข้าใช้แล้ว - โทร
IdentityProvider.close()
เพื่อปิดกล่องโต้ตอบ
แจ้งให้เบราว์เซอร์ทราบเกี่ยวกับสถานะการเข้าสู่ระบบของผู้ใช้
Login Status API เป็นกลไก ที่เว็บไซต์ โดยเฉพาะ IdP จะแจ้งสถานะการเข้าสู่ระบบของผู้ใช้ใน IdP ให้เบราว์เซอร์ทราบ API นี้ช่วยให้เบราว์เซอร์ลดคำขอที่ไม่จำเป็นไปยัง IdP และลดการโจมตีที่อาจเกิดขึ้นตามเวลา
IdP สามารถส่งสัญญาณสถานะการเข้าสู่ระบบของผู้ใช้ไปยังเบราว์เซอร์ได้โดยการส่งส่วนหัว HTTP หรือโดยการเรียกใช้ JavaScript API เมื่อผู้ใช้ลงชื่อเข้าใช้ใน IdP หรือเมื่อ ผู้ใช้ลงชื่อออกจากบัญชี IdP ทั้งหมด สำหรับ IdP แต่ละรายการ (ระบุโดย URL การกำหนดค่า) เบราว์เซอร์จะเก็บตัวแปรแบบ 3 สถานะที่แสดงสถานะการเข้าสู่ระบบ โดยมีค่าที่เป็นไปได้ดังนี้
logged-in
logged-out
unknown
(ค่าเริ่มต้น)
สถานะการเข้าสู่ระบบ | คำอธิบาย |
---|---|
logged-in |
เมื่อตั้งค่าสถานะการเข้าสู่ระบบของผู้ใช้เป็น logged-in RP ที่เรียกใช้ FedCM จะส่งคำขอไปยังปลายทางบัญชีของ IdP และแสดงบัญชีที่พร้อมใช้งานต่อผู้ใช้ในกล่องโต้ตอบ FedCM |
logged-out |
เมื่อสถานะการเข้าสู่ระบบของผู้ใช้เป็น logged-out การเรียกใช้ FedCM จะล้มเหลวโดยไม่มีการแจ้งเตือนโดยไม่ต้องส่งคำขอไปยังปลายทางบัญชีของ IdP |
unknown (ค่าเริ่มต้น) |
ระบบจะตั้งค่าสถานะ unknown ก่อนที่ IdP จะส่งสัญญาณโดยใช้ Login Status API เมื่อสถานะเป็น unknown เบราว์เซอร์จะส่งคำขอไปยังปลายทางบัญชีของ IdP และอัปเดตสถานะตามการตอบกลับจากปลายทางบัญชี |
หากต้องการส่งสัญญาณว่าผู้ใช้ลงชื่อเข้าใช้แล้ว ให้ส่งSet-Login: logged-in
ส่วนหัว HTTP
ในการนำทางระดับบนสุดหรือคำขอทรัพยากรย่อยแบบเดียวกันที่ต้นทาง IdP โดยทำดังนี้
Set-Login: logged-in
หรือจะเรียกใช้เมธอด JavaScript navigator.login.setStatus('logged-in')
จากต้นทาง IdP ในการนำทางระดับบนสุด
ก็ได้
navigator.login.setStatus('logged-in')
ระบบจะตั้งค่าสถานะการเข้าสู่ระบบของผู้ใช้เป็น logged-in
หากต้องการส่งสัญญาณว่าผู้ใช้ได้ออกจากระบบบัญชีทั้งหมดแล้ว ให้ส่งSet-Login: logged-out
ส่วนหัว HTTP ในการนำทางระดับบนสุดหรือคำขอทรัพยากรย่อยแบบเดียวกันที่ต้นทาง IdP ดังนี้
Set-Login: logged-out
หรือเรียกใช้ JavaScript API navigator.login.setStatus('logged-out')
จากต้นทาง IdP ในการนำทางระดับบนสุด
navigator.login.setStatus('logged-out')
ระบบจะตั้งค่าสถานะการเข้าสู่ระบบของผู้ใช้เป็น logged-out
ระบบจะตั้งค่าสถานะ unknown
ก่อนที่ IdP จะส่งสัญญาณโดยใช้ Login Status
API เบราว์เซอร์ส่งคำขอไปยังปลายทางบัญชีของ IdP และอัปเดตสถานะตามการตอบกลับจากปลายทางบัญชี
- หากปลายทางแสดงรายการบัญชีที่ใช้งานอยู่ ให้อัปเดตสถานะเป็น
logged-in
แล้วเปิดกล่องโต้ตอบ FedCM เพื่อแสดงบัญชีเหล่านั้น - หากปลายทางไม่แสดงบัญชี ให้อัปเดตสถานะเป็น
logged-out
และ ทำให้การเรียก FedCM ล้มเหลว
อนุญาตให้ผู้ใช้ลงชื่อเข้าใช้ผ่านโฟลว์การเข้าสู่ระบบแบบไดนามิก
แม้ว่า IdP จะแจ้งสถานะการเข้าสู่ระบบของผู้ใช้ให้เบราว์เซอร์ทราบอยู่เสมอ แต่สถานะอาจไม่ซิงค์กัน เช่น เมื่อเซสชันหมดอายุ เบราว์เซอร์พยายามส่งคำขอที่ต้องใช้ข้อมูลเข้าสู่ระบบไปยังปลายทางของบัญชีเมื่อสถานะการเข้าสู่ระบบเป็น logged-in
แต่เซิร์ฟเวอร์ไม่แสดงบัญชีเนื่องจากเซสชันไม่พร้อมใช้งานอีกต่อไป ในสถานการณ์เช่นนี้ เบราว์เซอร์จะอนุญาตให้ผู้ใช้ลงชื่อเข้าใช้ IdP ผ่านหน้าต่างป๊อปอัปแบบไดนามิกได้