ההטמעה של FedCM כוללת כמה שלבים מרכזיים גם לספק הזהויות (IdP) וגם לצד הנסמך (RP). במסמכי התיעוד מוסבר איך להטמיע את FedCM בצד של ה-RP.
IdPs צריכים להשלים את השלבים הבאים כדי להטמיע את FedCM:
- יוצרים קובץ well-known.
- יוצרים קובץ תצורה.
- יוצרים את נקודות הקצה הבאות:
- נקודת קצה של חשבון
- נקודת קצה לאימות זהויות
- [אופציונלי] ניתוק נקודת קצה
- [אופציונלי] נקודת קצה של מטא-נתונים של לקוח
- נקודת קצה להתחברות
- להודיע לדפדפן על סטטוס הכניסה של המשתמש.
יצירת קובץ well-known
כדי למנוע ממעקבים לנצל לרעה את ה-API, צריך להציג קובץ ידוע מ-/.well-known/web-identity
של eTLD+1 של ה-IdP.
הקובץ המוכר יכול לכלול את המאפיינים הבאים:
נכס | חובה | תיאור |
---|---|---|
provider_
|
חובה | מערך של נתיבים לקובצי תצורה של IdP. המערכת תתעלם מהמאפיין אם צוינו accounts_ ו-login_ (אבל הוא עדיין נדרש). |
accounts_
|
מומלץ, נדרש login_ |
כתובת ה-URL של נקודת הקצה של החשבונות. כך אפשר לתמוך בכמה הגדרות, כל עוד בכל קובץ תצורה נעשה שימוש באותן כתובות URL של login_ ו-accounts_ .הערה: יש תמיכה בפרמטר החל מגרסה 132 של Chrome. |
login_url
|
מומלץ, נדרש accounts_endpoint |
כתובת ה-URL של דף ההתחברות של המשתמש כדי להיכנס ל-IdP. כך אפשר לתמוך במספר הגדרות, כל עוד בכל קובץ תצורה נעשה שימוש באותם login_url ו-accounts_endpoint .הערה: הפרמטר נתמך החל מגרסה 132 של Chrome ואילך. |
לדוגמה, אם נקודות הקצה של ה-IdP מוצגות ב-https://accounts.idp.example/
, הן צריכות להציג קובץ well-known ב-https://idp.example/.well-known/web-identity
וגם קובץ תצורה של IdP. דוגמה לתוכן קובץ ידוע:
{
"provider_urls": ["https://accounts.idp.example/config.json"]
}
ספק זהויות יכול להכיל כמה קובצי תצורה, על ידי ציון הערכים accounts_endpoint
ו-login_url
בקובץ ה-well-known.
התכונה הזו יכולה להיות שימושית במקרים הבאים:
- ספק 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 מספק רשימה של נקודות קצה נדרשות לדפדפן. ספקי זהויות חייבים לארח קובץ תצורה אחד או יותר, ואת נקודות הקצה וכתובות ה-URL הנדרשות. כל התשובות בפורמט JSON חייבות להישלח עם סוג התוכן application/json
.
כתובת ה-URL של קובץ התצורה נקבעת לפי הערכים שסופקו לקריאה navigator.credentials.get()
שמתבצעת ב-RP.
const credential = await navigator.credentials.get({
identity: {
context: 'signup',
providers: [{
configURL: 'https://accounts.idp.example/config.json',
clientId: '********',
nonce: '******'
}]
}
});
const { token } = credential;
ה-RP מעביר את כתובת ה-URL של קובץ התצורה לקריאה ל-FedCM API כדי לאפשר למשתמש להיכנס:
// Executed on RP's side:
const credential = await navigator.credentials.get({
identity: {
context: 'signup',
providers: [{
// To allow users to sign in with an IdP using FedCM, RP specifies the IdP's config file URL:
configURL: 'https://accounts.idp.example/fedcm.json',
clientId: '********',
});
const { token } = credential;
הדפדפן יאתר את קובץ התצורה באמצעות בקשת GET
ללא הכותרת Origin
או הכותרת Referer
. לבקשה אין קובצי cookie והיא לא עוקבת אחרי הפניות אוטומטיות. כך, ספק הזהויות לא יכול לדעת מי שלח את הבקשה ואיזה RP מנסה להתחבר. לדוגמה:
GET /config.json HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity
ה-IdP צריך להטמיע נקודת קצה של תצורה שמחזירה תשובה בפורמט JSON. קובץ ה-JSON כולל את המאפיינים הבאים:
נכס | תיאור |
---|---|
accounts_endpoint (חובה) |
כתובת ה-URL של נקודת הקצה של החשבונות. |
ֶaccounts.include (אופציונלי)
|
מחרוזת תווית מותאמת אישית של חשבון, שמגדירה אילו חשבונות יוחזרו כשמשתמשים בקובץ התצורה הזה. לדוגמה: "accounts": {"include": "developer"} .
שירות IdP יכול להטמיע תיוג חשבונות בהתאמה אישית באופן הבא:
לדוגמה, IdP מטמיע קובץ תצורה של "https://idp.example/developer-config.json" עם "accounts": {"include": "developer"} שצוין. ה-IdP גם מסמן חשבונות מסוימים בתווית "developer" באמצעות הפרמטר labels בנקודת הקצה של החשבונות. כש-RP קורא ל-navigator.credentials.get() עם קובץ התצורה "https://idp.example/developer-config.json" שצוין, רק חשבונות עם התווית "developer" יחזרו.הערה: התמיכה בתוויות חשבון בהתאמה אישית מתחילה ב-Chrome 132. |
ֶ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 (אופציונלי) |
מערך של אובייקטי סמלים. הסמלים האלה מוצגים בתיבת הדו-שיח של הכניסה. לאובייקט הסמל יש שני פרמטרים:
|
modes |
אובייקט שמכיל מפרטים לגבי אופן הצגת ממשק המשתמש של FedCM במצבים שונים:
|
modes.active
|
אובייקט שמכיל מאפיינים שמאפשרים להתאים אישית את ההתנהגות של FedCM במצב ספציפי. גם modes.active וגם modes.passive יכולים להכיל את הפרמטר הבא:
הערה: התכונה 'שימוש בחשבון אחר' והמצב הפעיל נתמכים בגרסה 132 של Chrome ואילך. |
modes.passive
|
זוהי דוגמה לגוף תגובה מה-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.
"accounts": {"include": "developer"},
"modes": {
"active": {
"supports_use_other_account": true,
}
},
"branding": {
"background_color": "green",
"color": "#FFEEAA",
"icons": [{
"url": "https://idp.example/icon.ico",
"size": 25
}]
}
}
אחרי שהדפדפן מאחזר את קובץ התצורה, הוא שולח בקשות נוספות לנקודות הקצה של ה-IdP:
![נקודות קצה של IdP](https://developers.google.com/static/privacy-sandbox/assets/images/fedcm/fedcm-flow-diagram.png?authuser=8&hl=he)
שימוש בחשבון אחר
משתמשים יכולים לעבור לחשבון שונה מזה שאליו הם מחוברים כרגע, אם ה-IdP תומך במספר חשבונות או מחליף את החשבון הקיים.
כדי לאפשר למשתמש לבחור חשבונות אחרים, ה-IdP צריך לציין את התכונה הזו בקובץ התצורה:
{
"accounts_endpoint" : "/accounts.example",
"modes": {
"active": {
// Allow the user to choose other account (false by default)
"supports_use_other_account": true
}
// "passive" mode can be configured separately
}
}
נקודת הקצה של חשבונות
נקודת הקצה של החשבונות ב-IdP מחזירה רשימה של חשבונות שהמשתמש נכנס אליהם ב-IdP. אם ה-IdP תומך בכמה חשבונות, נקודת הקצה הזו תחזיר את כל החשבונות שנכנסו.
הדפדפן שולח בקשת GET
עם קובצי cookie עם 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
כשהבקשה תתקבל, השרת צריך:
- מוודאים שהבקשה מכילה כותרת HTTP
Sec-Fetch-Dest: webidentity
. - התאמת קובצי ה-cookie של הסשן למזהים של החשבונות שכבר נכנסתם אליהם.
- משיבים עם רשימת החשבונות.
הדפדפן מצפה לתגובת JSON שכוללת את המאפיין accounts
עם מערך של פרטי החשבון עם המאפיינים הבאים:
נכס | תיאור |
---|---|
id (חובה) |
המזהה הייחודי של המשתמש. |
name (חובה) |
השם הפרטי ושם המשפחה של המשתמש. |
email (חובה) |
כתובת האימייל של המשתמש. |
ֶgiven_name (אופציונלי) |
השם הפרטי של המשתמש. |
ֶpicture (אופציונלי) |
כתובת ה-URL של תמונת הדמות של המשתמש. |
ֶapproved_clients (אופציונלי) |
מערך של מזהי לקוח של RP שהמשתמש רשם. |
ֶlogin_hints (אופציונלי) |
מערך של כל סוגי המסננים האפשריים ש-IdP תומך בהם כדי לציין חשבון. ה-RP יכול להפעיל את navigator.credentials.get() עם המאפיין loginHint כדי להציג באופן סלקטיבי את החשבון שצוין. |
ֶdomain_hints (אופציונלי) |
מערך של כל הדומיינים שהחשבון משויך אליהם. ה-RP יכול להפעיל את navigator.credentials.get() עם נכס domainHint כדי לסנן את החשבונות. |
ֶlabels (אופציונלי)
|
מערך של מחרוזות של תוויות חשבון בהתאמה אישית שחשבון משויך אליהן. שירות IdP יכול להטמיע תיוג חשבונות בהתאמה אישית באופן הבא:
לדוגמה, IdP מטמיע קובץ תצורה של https://idp.example/developer-config.json עם "accounts": {"include": "developer"} שצוין. ה-IdP גם מסמנים חשבונות מסוימים בתווית "developer" באמצעות הפרמטר labels ב נקודת הקצה לחשבונות. כש-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.
"labels": ["hr", "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.
נקודת קצה לאישור זהות
נקודת הקצה של טענת הנכוֹנוּת (assertion) של הזהות ב-IdP מחזירה טענת נכוֹנוּת למשתמש המחובר.
כשהמשתמש נכנס לאתר של RP באמצעות קריאה ל-navigator.credentials.get()
, הדפדפן שולח בקשת POST
עם קובצי cookie עם SameSite=None
וסוג תוכן application/x-www-form-urlencoded
לנקודת הקצה הזו עם הפרטים הבאים:
נכס | תיאור |
---|---|
client_id (חובה) |
מזהה הלקוח של RP. |
account_id (חובה) |
המזהה הייחודי של המשתמש שנכנס לחשבון. |
disclosure_text_shown |
הפונקציה מחזירה מחרוזת של "true" או "false" (במקום ערך בוליאני). התוצאה היא "false" במקרים הבאים:
|
is_auto_selected |
אם מתבצעת אימות חוזר אוטומטי ב-RP, הערך של is_auto_selected הוא "true" . אחרת "false" . כך אפשר לתמוך בתכונות נוספות שקשורות לאבטחה. לדוגמה, יכול להיות שחלק מהמשתמשים יעדיפו רמת אבטחה גבוהה יותר שמחייבת התערבות מפורשת של המשתמש באימות. אם IdP מקבל בקשה לאסימון ללא תהליך בחירת הרשת, הוא יכול לטפל בבקשה בצורה שונה. לדוגמה, אפשר להחזיר קוד שגיאה כדי שה-RP יוכל לקרוא שוב ל-FedCM API עם mediation: required . |
ֶfields (אופציונלי)
|
מערך של מחרוזות שמציין את פרטי המשתמש ('name', 'email', 'picture') ש-RP צריך ש-IdP ישתף איתו. הדפדפן ישלח את fields , disclosure_text_shown ו-disclosure_shown_for עם פירוט השדות שצוינו בבקשת ה-POST, כמו בדוגמה הבאה.הערה: הפרמטר Fields נתמך החל מגרסה 132 של Chrome. |
ֶparams (אופציונלי)
|
כל אובייקט JSON תקין שמאפשר לציין פרמטרים נוספים של מפתח/ערך בהתאמה אישית, לדוגמה:
params ישודר בפורמט JSON ולאחר מכן יקודר לפי אחוזים.הערה: ה-API של הפרמטרים נתמך ב-Chrome מגרסה 132 ואילך. |
דוגמה לכותרת 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&disclosure_text_shown=true&fields=email,picture&disclosure_shown_for=email,picture
כשהבקשה תתקבל, השרת צריך:
- מענה לבקשה באמצעות CORS (שיתוף משאבים בין מקורות).
- מוודאים שהבקשה מכילה כותרת HTTP
Sec-Fetch-Dest: webidentity
. - התאמת הכותרת
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 להפניה אוטומטית בתשובה של נקודת הקצה של טענת הנכוֹנוּת (assertion) של הזהות כדי לאפשר תהליך כניסה בן כמה שלבים. האפשרות הזו שימושית כש-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 במצבי תיווך שונים:
- במצב פסיבי:
mediation: 'optional'
(ברירת המחדל): ממשק ה-Continuation API יפעל רק עם תנועת משתמש, כמו לחיצה על לחצן בדף או בממשק המשתמש של FedCM. כשהאימות מחדש האוטומטי מופעל ללא תנועת משתמש, לא נפתח חלון קופץ וההבטחה נדחית.mediation: 'required'
: תמיד מופיעה בקשה למשתמש לבצע פעולה, כך ש-Continuation API תמיד פועל.
- במצב פעיל:
- תמיד נדרשת הפעלה של המשתמש. ממשק ה-Continuation API תואם.
אם מסיבה כלשהי המשתמש שינה את החשבון שלו בחלון הקופץ (לדוגמה, ה-IdP מציע את הפונקציה 'שימוש בחשבון אחר', או במקרים של הענקת גישה), קריאת הפתרון מקבלת ארגומנטים שניים אופציונליים שמאפשרים משהו כמו:
IdentityProvider.resolve(token, {accountId: '1234');
החזרת הודעת שגיאה
ה-id_assertion_endpoint
יכול גם להחזיר תשובה מסוג 'error', עם שני שדות אופציונליים:
code
: ה-IdP יכול לבחור באחת מהשגיאות המוכרות מרשימת השגיאות שצוינה ב-OAuth 2.0 (invalid_request
, unauthorized_client
, access_denied
, server_error
ו-temporarily_unavailable
) או להשתמש בכל מחרוזת שרירותית. אם זה המצב, Chrome ייצור את ממשק המשתמש של השגיאה עם הודעת שגיאה כללית ויעביר את הקוד ל-RP.url
: הוא מזהה דף אינטרנט שקריא לאנשים עם מידע על השגיאה, כדי לספק למשתמשים מידע נוסף עליה. השדה הזה שימושי למשתמשים כי הדפדפנים לא יכולים לספק הודעות שגיאה עשירות בממשק משתמש מובנה. לדוגמה: קישורים לשלבים הבאים או פרטים ליצירת קשר עם שירות הלקוחות. אם משתמש רוצה לקבל מידע נוסף על פרטי השגיאה ועל הדרך לתקן אותה, הוא יכול להיכנס לדף שסופק מתוך ממשק המשתמש של הדפדפן. כתובת ה-URL צריכה להיות באותו אתר כמו ה-IdPconfigURL
.
// id_assertion_endpoint response
{
"error" : {
"code": "access_denied",
"url" : "https://idp.example/error?type=access_denied"
}
}
תוויות חשבון בהתאמה אישית
באמצעות תוויות חשבון בהתאמה אישית, ה-IdP יכול להוסיף הערות לחשבונות משתמשים באמצעות תוויות, וה-RP יכול לבחור לאחזר רק חשבונות עם תוויות ספציפיות על ידי ציון הערך configURL
של התווית הספציפית הזו. האפשרות הזו שימושית כשחשבון RP צריך לסנן חשבונות לפי קריטריונים ספציפיים, למשל כדי להציג רק חשבונות ספציפיים לתפקיד, כמו "developer"
או "hr"
.
אפשר לבצע סינון דומה באמצעות התכונות Domain Hint ו-Login Hint, על ידי ציון שלהן בקריאה navigator.credentials.get()
. עם זאת, תוויות חשבון בהתאמה אישית יכולות לסנן משתמשים על ידי ציון קובץ התצורה, וזו תכונה שימושית במיוחד כשמשתמשים בכמה כתובות URL של קובצי תצורה. תוויות חשבון בהתאמה אישית שונות גם בכך שהן מסופקות משרת ה-IdP, בניגוד ל-RP, כמו טיפים להתחברות או לדומיין.
נניח ש-IdP רוצה להבדיל בין חשבונות "developer"
לבין חשבונות "hr"
. כדי לעשות זאת, ה-IdP צריך לתמוך בשתי כתובות configURL עבור "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",
"accounts": {
// Account label
"include": "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",
"accounts": {
// Account label
"include": "hr"
}
}
- בהגדרה כזו, הקובץ הידוע צריך לכלול את
accounts_endpoint
ואתlogin_url
כדי לאפשר כמה configURLs:
{
"provider_urls": [ "https://idp.example/fedcm.json" ],
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
- נקודת הקצה (endpoint) של חשבונות המשותפת ל-IdP (בדוגמאות האלה היא
https://idp.example/accounts
) מחזירה רשימה של חשבונות שכוללת את הנכסlabels
עם תוויות שהוקצו במערך לכל חשבון:
{
"accounts": [{
"id": "123",
"given_name": "John",
"name": "John Doe",
"email": "john_doe@idp.example",
"picture": "https://idp.example/profile/123",
"labels": ["developer"]
}], [{
"id": "4567",
"given_name": "Jane",
"name": "Jane Doe",
"email": "jane_doe@idp.example",
"picture": "https://idp.example/profile/4567",
"labels": ["hr"]
}]
}
כש-RP רוצה לאפשר למשתמשים ב-"hr"
להיכנס לחשבון, הוא יכול לציין את ה-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 באתר הזה.
- תוויות הן מחרוזות. אם המערך
labels
או השדהinclude
מכילים משהו שאינו מחרוזת, המערכת תתעלם ממנו. - אם לא יצוינו תוויות ב-
configURL
, כל החשבונות יוצגו בבורר החשבונות של FedCM. - אם לא צוינו תוויות לחשבון, הוא יוצג בבורר החשבונות רק אם גם ב-
configURL
לא צוינה תווית. - אם אין חשבון שמתאים לתווית המבוקשת במצב פסיבי (בדומה לתכונה 'רמז לדומיין'), בתיבת הדו-שיח של FedCM תוצג בקשה להתחברות, שמאפשרת למשתמש להיכנס לחשבון IdP. במצב פעיל, חלון הקופץ של ההתחברות נפתח ישירות.
ניתוק נקודת הקצה
כשמפעילים את IdentityCredential.disconnect()
, הדפדפן שולח בקשת POST
חוצת-מקור עם קובצי cookie עם 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 (שיתוף משאבים בין מקורות).
- מוודאים שהבקשה מכילה כותרת HTTP
Sec-Fetch-Dest: webidentity
. - התאמת הכותרת
Origin
למקור ה-RP שנקבע על ידיclient_id
. אם הם לא תואמים, דוחים אותם. - מתאימים את
account_hint
למזהים של החשבונות שכבר נכנסתם אליהם. - מנתקים את חשבון המשתמש מה-RP.
- מענה לדפדפן עם פרטי חשבון המשתמש שזוהו בפורמט JSON.
דוגמה למטען ייעודי (payload) של JSON בתגובה:
{
"account_id": "account456"
}
במקום זאת, אם ה-IdP רוצה שהדפדפן ינתק את כל החשבונות המשויכים ל-RP, צריך להעביר מחרוזת שלא תואמת למספר חשבון כלשהו, למשל "*"
.
נקודת קצה של מטא-נתונים של לקוח
נקודת הקצה של המטא-נתונים של הלקוח ב-IdP מחזירה את המטא-נתונים של הצד הנסמך, כמו מדיניות הפרטיות, התנאים וההגבלות ואיקוני הלוגו של ה-RP. ספקי ה-RP צריכים לספק מראש ל-IdP קישורים למדיניות הפרטיות ולתנאים ולהגבלות שלהם. הקישורים האלה מוצגים בתיבת הדו-שיח של הכניסה לחשבון כשהמשתמש עדיין לא רשום ב-RP דרך ה-IdP.
הדפדפן שולח בקשת GET
באמצעות client_id
navigator.credentials.get
ללא קובצי cookie. לדוגמה:
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 של דף ההתחברות שצוינה ב-login_url
של קובץ התצורה של ה-IdP.
בתיבת הדו-שיח של FedCM תוצג הודעה עם הצעה להיכנס לחשבון, כפי שמוצג בתמונה הבאה.
![A](https://developers.google.com/static/privacy-sandbox/assets/images/blog/fedcm-120-1.png?authuser=8&hl=he)
כשהמשתמש לוחץ על הלחצן המשך, נפתח בדפדפן חלון קופץ של דף ההתחברות של ה-IdP.
![דוגמה לתיבת דו-שיח של FedCM.](https://developers.google.com/static/privacy-sandbox/assets/images/fedcm-dialog-example.png?authuser=8&hl=he)
תיבת הדו-שיח היא חלון דפדפן רגיל עם קובצי cookie מהדומיין הנוכחי. כל מה שקורה בתיבת הדו-שיח תלוי ב-IdP, ואין מזהי חלונות זמינים ליצירת בקשת תקשורת בין מקורות לדף ה-RP. אחרי שהמשתמש נכנס לחשבון, ה-IdP צריך:
- שולחים את הכותרת
Set-Login: logged-in
או קוראים ל-APInavigator.login.setStatus("logged-in")
כדי להודיע לדפדפן שהמשתמש נכנס לחשבון. - מקישים על
IdentityProvider.close()
כדי לסגור את תיבת הדו-שיח.
עדכון הדפדפן לגבי סטטוס הכניסה של המשתמש
Login Status API הוא מנגנון שבו אתר, במיוחד IdP, מודיע לדפדפן על סטטוס הכניסה של המשתמש ב-IdP. בעזרת ה-API הזה, הדפדפן יכול לצמצם את מספר הבקשות הלא נחוצות ל-IdP ולהפחית את הסיכון למתקפות תזמון פוטנציאליות.
ספקי IdP יכולים לשלוח כותרת HTTP או להפעיל ממשק API של JavaScript כדי לסמן לדפדפן את סטטוס הכניסה של המשתמש, כשהמשתמש מחובר ל-IdP או כשהמשתמש יוצא מכל חשבונות ה-IdP שלו. לכל IdP (שזוהה לפי כתובת ה-URL של ההגדרה שלו), הדפדפן שומר משתנה בן שלוש ערכים שמייצג את מצב ההתחברות, עם הערכים האפשריים הבאים:
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 ומעדכן את הסטטוס על סמך התשובה מנקודת הקצה של החשבונות. |
כדי לסמן שהמשתמש מחובר, שולחים כותרת HTTP Set-Login: logged-in
בבקשת ניווט ברמה העליונה או בבקשה לשימוש במשאב משנה באותו אתר במקור של ה-IdP:
Set-Login: logged-in
לחלופין, אפשר להפעיל את שיטת ה-JavaScript navigator.login.setStatus('logged-in')
ממקור ה-IdP בניווט ברמה העליונה:
navigator.login.setStatus('logged-in')
סטטוס ההתחברות של המשתמש יוגדר כ-logged-in
.
כדי לסמן שהמשתמש יצא מכל החשבונות שלו, שולחים כותרת HTTP Set-Login: logged-out
בתפריט הניווט ברמה העליונה או בקשה למשאב משנה באותו אתר במקור של ה-IdP:
Set-Login: logged-out
לחלופין, אפשר לבצע קריאה ל-JavaScript API navigator.login.setStatus('logged-out')
ממקור ה-IdP בניווט ברמה העליונה:
navigator.login.setStatus('logged-out')
סטטוס ההתחברות של המשתמש יוגדר כ-logged-out
.
הסטטוס unknown
מוגדר לפני שה-IdP שולח אות באמצעות ה-API של סטטוס הכניסה. הדפדפן שולח בקשה לנקודת הקצה לחשבונות של ה-IdP ומעדכן את הסטטוס על סמך התשובה מנקודת הקצה לחשבונות:
- אם נקודת הקצה מחזירה רשימה של חשבונות פעילים, מעדכנים את הסטטוס ל-
logged-in
ופותחים את תיבת הדו-שיח של FedCM כדי להציג את החשבונות האלה. - אם נקודת הקצה לא מחזירה חשבונות, מעדכנים את הסטטוס ל-
logged-out
ומכשילים את הקריאה ל-FedCM.
לאפשר למשתמש להיכנס לחשבון דרך תהליך כניסה דינמי
למרות ש-IdP ממשיך לעדכן את סטטוס ההתחברות של המשתמש בדפדפן, יכול להיות שהסנכרון לא יהיה תקין, למשל כשיפוג התוקף של הסשן. הדפדפן מנסה לשלוח בקשה עם פרטי כניסה לנקודת הקצה של החשבונות כשסטטוס ההתחברות הוא logged-in
, אבל השרת לא מחזיר חשבונות כי הסשן כבר לא זמין. בתרחיש כזה, הדפדפן יכול לאפשר למשתמש להיכנס באופן דינמי ל-IdP דרך חלון קופץ.