FedCM (ניהול מאוחד של פרטי כניסה) היא גישה לשמירה על הפרטיות בשירותי אימות זהות מאוחדים (כמו 'כניסה באמצעות…') שמאפשרת למשתמשים להתחבר לאתרים בלי לשתף את המידע האישי שלהם עם שירות הזהות או עם האתר.
ההטמעה של FedCM כוללת כמה שלבים מרכזיים גם ל-IdP (ספק הזהויות) וגם ל-RP (הצד הנסמך).
IdPs צריכים להשלים את השלבים הבאים כדי להטמיע את FedCM:
- יוצרים קובץ well-known.
- יוצרים קובץ תצורה.
- יוצרים את נקודות הקצה הבאות:
- נקודת קצה של חשבון
- נקודת קצה לאימות זהויות
- [אופציונלי] ניתוק נקודת קצה
- [אופציונלי] נקודת קצה של מטא-נתונים של לקוח
- נקודת קצה להתחברות
- להודיע לדפדפן על סטטוס הכניסה של המשתמש.
בעלי תוכן דיגיטלי צריכים לבצע את השלבים הבאים כדי להפעיל את FedCM באתר שלהם:
- מוודאים שנקודות הקצה של FedCM מותרות באתר של RP.
- משתמשים ב-FedCM JavaScript API כדי להתחיל את אימות המשתמש.
- לספק את המטא-נתונים שלהם (כמו כתובות URL של מדיניות הפרטיות ותנאי השירות) ל-IdP
- [אופציונלי] התאמה אישית של חוויית המשתמש: בוחרים מצב חוויית משתמש, מספקים פרטי כניסה או רמזים לדומיין, מעבירים פרמטרים מותאמים אישית, מבקשים פרטי משתמש ספציפיים, מספקים הודעת שגיאה מותאמת אישית או בוחרים איך לבצע אימות מחדש של משתמשים.
הטמעת FedCM כ-IdP
מידע נוסף על השלבים להטמעת FedCM בצד ה-IdP
יצירת קובץ well-known
כדי למנוע משירותי מעקב לנצל לרעה את ה-API, צריך להציג קובץ well-known מ-/.well-known/web-identity
של eTLD+1 של ה-IdP.
הקובץ המוכר יכול לכלול את המאפיינים הבאים:
נכס | חובה | תיאור |
---|---|---|
provider_urls
|
חובה | מערך של נתיבים לקובצי תצורה של IdP. המערכת תתעלם מהמאפיין אם צוינו accounts_endpoint ו-login_url (אבל הוא עדיין נדרש). |
accounts_endpoint
|
מומלץ, נדרש login_url |
כתובת ה-URL של נקודת הקצה של החשבונות. כך אפשר לתמוך בכמה הגדרות, כל עוד בכל קובץ תצורה נעשה שימוש באותן כתובות URL של login_url ו-accounts_endpoint .הערה: יש תמיכה בפרמטר החל מגרסה 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. דוגמה לתוכן של קובץ well-known:
{
"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 מספק רשימה של נקודות קצה נדרשות לדפדפן. שירותי 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 והיא לא עוקבת אחרי הפניות אוטומטיות.
כך אפשר למנוע מה-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 של נקודת הקצה של החשבונות. |
ֶ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" יחזרו.
|
ֶ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 תומך במספר חשבונות או בהחלפת החשבון הקיים.
כדי לאפשר למשתמש לבחור חשבונות אחרים, ה-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 מציין רק את קובץ התצורה שבו יש להשתמש. |
דוגמה לגוף התגובה:
{
"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 להפניה אוטומטית בתגובה של נקודת הקצה של טענת הנכוֹנוּת של הזהות כדי לאפשר תהליך כניסה בן כמה שלבים. האפשרות הזו שימושית כש-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()
. עם זאת, תוויות חשבון בהתאמה אישית יכולות לסנן משתמשים על ידי ציון קובץ התצורה, וזו תכונה שימושית במיוחד כשמשתמשים במספר configURLs. ההבדל בין תוויות חשבון בהתאמה אישית לבין הנחיות להתחברות או לדומיין הוא שהן מסופקות על ידי שרת ה-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 תוצג הודעה עם הצעה להיכנס לחשבון, כפי שמוצג בתמונה הבאה.
כשהמשתמש לוחץ על הלחצן המשך, נפתח בדפדפן חלון קופץ של דף ההתחברות של ה-IdP.
תיבת הדו-שיח היא חלון דפדפן רגיל עם קובצי cookie מהדומיין הנוכחי. כל מה שקורה בתיבת הדו-שיח תלוי ב-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 של ההגדרה שלו), הדפדפן שומר משתנה בן שלוש ערכים שמייצג את מצב ההתחברות, עם הערכים האפשריים הבאים:
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 שולח אות באמצעות Login Status API. הדפדפן שולח בקשה לנקודת הקצה לחשבונות של ה-IdP ומעדכן את הסטטוס על סמך התשובה מנקודת הקצה לחשבונות:
- אם נקודת הקצה מחזירה רשימה של חשבונות פעילים, מעדכנים את הסטטוס ל-
logged-in
ופותחים את תיבת הדו-שיח של FedCM כדי להציג את החשבונות האלה. - אם נקודת הקצה לא מחזירה חשבונות, מעדכנים את הסטטוס ל-
logged-out
ומכשילים את הקריאה ל-FedCM.
לאפשר למשתמש להיכנס לחשבון דרך תהליך כניסה דינמי
למרות ש-IdP ממשיך לעדכן את סטטוס ההתחברות של המשתמש בדפדפן, יכול להיות שהסנכרון לא יהיה תקין, למשל כשיפוג התוקף של הסשן. הדפדפן מנסה לשלוח בקשה עם פרטי כניסה לנקודת הקצה של החשבונות כשסטטוס ההתחברות הוא logged-in
, אבל השרת לא מחזיר חשבונות כי הסשן כבר לא זמין. בתרחיש כזה, הדפדפן יכול לאפשר למשתמש להיכנס באופן דינמי ל-IdP דרך חלון קופץ.
הטמעת FedCM כגורם מוגבל (RP)
אחרי שההגדרות ונקודות הקצה של ה-IdP יהיו זמינות, ספקי ה-RP יוכלו לבצע קריאה ל-navigator.credentials.get()
כדי לבקש הרשאה למשתמשים להיכנס ל-RP באמצעות ה-IdP.
לפני שמפעילים את ה-API, צריך לוודא ש-FedCM זמין בדפדפן של המשתמש. כדי לבדוק אם FedCM זמין, צריך להוסיף את הקוד הזה להטמעת FedCM:
if ('IdentityCredential' in window) {
// If the feature is available, take action
} else {
// FedCM is not supported, use a different identity solution
}
כדי לאפשר למשתמשים להיכנס ל-IdP ב-RP באמצעות FedCM, ה-RP יכול לקרוא ל-navigator.credentials.get()
. לדוגמה:
const credential = await navigator.credentials.get({
identity: {
context: 'signin',
providers: [{
configURL: 'https://accounts.idp.example/config.json',
clientId: '********',
mode: 'active',
params: {
nonce: '******'
}
}]
}
});
const { token } = credential;
מאפיין הקשר
באמצעות המאפיין האופציונלי context
, ה-RP יכול לשנות את המחרוזת בממשק המשתמש של תיבת הדו-שיח של FedCM (לדוגמה, 'כניסה אל rp.example…', 'שימוש ב-idp.example…') כדי להתאים להקשרי אימות מוגדרים מראש, למשל. המאפיין context
יכול לקבל את הערכים הבאים:
-
signin
(ברירת מחדל) signup
use
לדוגמה, הגדרת context
ל-use
תוביל להודעה הבאה:
הדפדפן מטפל בתרחישים לדוגמה של הרשמה וכניסה באופן שונה, בהתאם לנוכחות של approved_clients
בתגובה מנקודת הקצה של רשימת החשבונות. בדפדפן לא יוצג טקסט של גילוי נאות "To continue with ...." אם המשתמש כבר נרשם ל-RP.
הנכס providers
מקבל מערך של אובייקטים מסוג IdentityProvider שיש להם את המאפיינים הבאים:
המאפיין Providers
הנכס providers
מקבל מערך של אובייקטים מסוג IdentityProvider
שיש להם את המאפיינים הבאים:
נכס | תיאור |
---|---|
configURL (חובה) |
הנתיב המלא של קובץ התצורה של ה-IdP. |
clientId (חובה) |
מזהה הלקוח של RP, שהונפק על ידי ה-IdP. |
ֶnonce (אופציונלי) |
מחרוזת אקראית כדי לוודא שהתגובה תישלח לגבי הבקשה הספציפית הזו. מניעת התקפות שחזור. |
ֶloginHint (אופציונלי) |
כשמציינים אחד מהערכים של login_hints שסופקו על ידי נקודות הקצה של החשבונות, בתיבת הדו-שיח של FedCM מוצג באופן סלקטיבי החשבון שצוין. |
ֶdomainHint (אופציונלי) |
כדי להציג באופן סלקטיבי את החשבון שצוין בתיבת הדו-שיח של FedCM, מציינים אחד מהערכים של domain_hints שסופקו על ידי נקודות הקצה של החשבונות. |
ֶmode (אופציונלי) |
מחרוזת שמציינת את מצב ממשק המשתמש של FedCM. הערך יכול להיות אחד מהערכים הבאים:
הערה: הפרמטר mode נתמך החל מגרסה 132 של Chrome.
|
ֶfields (אופציונלי) |
מערך של מחרוזות שמציין את פרטי המשתמש ('name', 'email', 'picture') ש-RP צריך ש-IdP ישתף איתו. הערה: Field API נתמך ב-Chrome מגרסה 132 ואילך. |
ֶparameters (אופציונלי) |
אובייקט מותאם אישית שמאפשר לציין פרמטרים נוספים של מפתח/ערך:
הערה: התמיכה ב- parameters מתחילה ב-Chrome 132.
|
מצב פעיל
FedCM תומך בהגדרות שונות של סטטוס UX. מצב פסיבי הוא מצב ברירת המחדל, והמפתחים לא צריכים להגדיר אותו.
כדי להשתמש ב-FedCM במצב פעיל:
- בודקים את הזמינות של התכונה בדפדפן של המשתמש.
- קריאה ל-API באמצעות תנועת משתמש זמנית, כמו לחיצה על לחצן.
- מעבירים את הפרמטר
mode
לקריאה ל-API:
let supportsFedCmMode = false;
try {
navigator.credentials.get({
identity: Object.defineProperty(
// Check if this Chrome version supports the Mode API.
{}, 'mode', {
get: function () { supportsFedCmMode = true; }
}
)
});
} catch(e) {}
if (supportsFedCmMode) {
// The button mode is supported. Call the API with mode property:
return await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/config.json',
clientId: '123',
}],
// The 'mode' value defines the UX mode of FedCM.
// - 'active': Must be initiated by user interaction (e.g., clicking a button).
// - 'passive': Can be initiated without direct user interaction.
mode: 'active'
}
});
}
סמל מותאם אישית במצב פעיל
המצב הפעיל מאפשר ל-IdPs לכלול את סמל הלוגו הרשמי של RP ישירות בתשובה של נקודת הקצה של המטא-נתונים של הלקוח. ה-RP צריך לספק מראש את נתוני המיתוג שלו.
קריאה ל-FedCM מתוך iframe חוצה-מקורות
אפשר להפעיל את FedCM מתוך iframe בין מקורות באמצעות מדיניות הרשאות identity-credentials-get
, אם מסגרת ההורה מאפשרת זאת. כדי לעשות זאת, צריך לצרף את המאפיין allow="identity-credentials-get"
לתג iframe באופן הבא:
<iframe src="https://fedcm-cross-origin-iframe.glitch.me" allow="identity-credentials-get"></iframe>
אפשר לראות את הפעולה הזו בדוגמה.
אם מסגרת ההורה רוצה להגביל את מקורות הקריאה ל-FedCM, אפשר לשלוח כותרת Permissions-Policy
עם רשימה של מקורות מותרים.
Permissions-Policy: identity-credentials-get=(self "https://fedcm-cross-origin-iframe.glitch.me")
מידע נוסף על האופן שבו פועלת מדיניות ההרשאות זמין במאמר שליטה בתכונות הדפדפן באמצעות מדיניות ההרשאות.
Login Hint API
בעזרת ההצעה להתחברות, ה-RP יכול להמליץ איזה חשבון המשתמש צריך להשתמש בו כדי להיכנס. זה יכול להיות שימושי לביצוע אימות מחדש של משתמשים שלא בטוחים באיזה חשבון הם השתמשו בעבר.
כדי להציג חשבון ספציפי באופן סלקטיבי, חשבונות משתמשים מורשים יכולים להפעיל את navigator.credentials.get()
עם הנכס loginHint
עם אחד מערכי login_hints
שאוחזר מנקודת הקצה של רשימת החשבונות, כפי שמוצג בדוגמת הקוד הבאה:
return await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/manifest.json',
clientId: '123',
// Accounts endpoint can specify a 'login_hints' array for an account.
// When RP specifies a 'exampleHint' value, only those accounts will be
// shown to the user whose 'login_hints' array contains the 'exampleHint'
// value
loginHint : 'exampleHint'
}]
}
});
אם אין חשבונות שתואמים ל-loginHint
, בתיבת הדו-שיח של FedCM תוצג בקשה להתחברות, שמאפשרת למשתמש להתחבר לחשבון IdP שתואם לטיפת המידע שביקשה ה-RP. כשהמשתמש מקייש על ההנחיה, נפתח חלון קופץ עם כתובת ה-URL להתחברות שצוינה בקובץ התצורה. לאחר מכן, הקישור יתווספו לו פרמטרים של שאילתות של רמז להתחברות ורמז לדומיין.
Domain Hint API
ספקי RP יכולים להציג באופן סלקטיבי רק חשבונות שמשויכים לדומיין מסוים. האפשרות הזו יכולה להיות שימושית לחשבונות RP שמוגבלים לדומיין עסקי.
כדי להציג רק חשבונות דומיין ספציפיים, ה-RP צריך לבצע קריאה ל-navigator.credentials.get()
עם המאפיין domainHint
עם אחד מערכי domain_hints
שאוחזר מנקודת הקצה של רשימת החשבונות, כפי שמתואר בדוגמת הקוד הבאה:
return await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/manifest.json',
clientId: 'abc',
// Accounts endpoint can specify a 'domain_hints' array for an account.
// When RP specifies a '@domain.example' value, only those accounts will be
// shown to the user whose 'domain_hints' array contains the
// '@domain.example' value
domainHint : '@domain.example'
}]
}
});
אם אין חשבונות שתואמים ל-domainHint
, בתיבת הדו-שיח של FedCM תוצג בקשה להתחברות, שמאפשרת למשתמש להתחבר לחשבון IdP שתואם לטיפת המידע שביקשה ה-RP. כשהמשתמש מקייש על ההנחיה, נפתח חלון קופץ עם כתובת ה-URL להתחברות שצוינה בקובץ התצורה. לאחר מכן, הקישור יתווספו לו פרמטרים של שאילתות של רמז להתחברות ורמז לדומיין.
פרמטרים מותאמים אישית
התכונה 'פרמטרים מותאמים אישית' מאפשרת ל-RP לספק פרמטרים נוספים של מפתח/ערך לנקודת הקצה של טענת הנכוֹנוּת (assertion) של הזהות. באמצעות Parameters API, ספקי ה-RP יכולים להעביר פרמטרים נוספים ל-IdP כדי לבקש הרשאות למשאבים מעבר לכניסה בסיסית. העברת פרמטרים נוספים יכולה להיות שימושית בתרחישים הבאים:
- ה-RP צריך לבקש באופן דינמי הרשאות נוספות שיש ל-IdP, כמו כתובת לחיוב או גישה ליומן. המשתמש יכול לאשר את ההרשאות האלה באמצעות תהליך UX שנשלט על ידי ה-IdP, שמופעל באמצעות התכונה 'המשך'. לאחר מכן, ה-IdP ישתף את המידע הזה.
כדי להשתמש ב-API, ה-RP מוסיף פרמטרים לנכס params
כאובייקט בקריאה navigator.credentials.get()
:
let {token} = await navigator.credentials.get({
identity: {
providers: [{
clientId: '1234',
configURL: 'https://idp.example/fedcm.json',
// Key/value pairs that need to be passed from the
// RP to the IdP but that don't really play any role with
// the browser.
params: {
IDP_SPECIFIC_PARAM: '1',
foo: 'BAR'
}
},
}
});
הדפדפן יתרגם את זה באופן אוטומטי לבקשת POST ל-IdP עם פרמטרים כאובייקט יחיד של JSON שעבר סריאליזציה וקידוד ככתובת URL:
// The assertion endpoint is drawn from the config file
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
// params are translated into urlencoded version of `{"IDP_SPECIFIC_PARAM":"1","foo":"bar"}`
account_id=123&client_id=client1234¶ms=%22%7B%5C%22IDP_SPECIFIC_PARAM%5C%22%3A1%2C%5C%22foo%5C%22%3A%5C%22BAR%5C%22%7D%22.
אם ל-RP נדרשות הרשאות נוספות, ה-IdP יכול לספק קישור להפניה אוטומטית. לדוגמה, ב-node.js:
if (rpRequestsPermissions) {
// Response with a URL if the RP requests additional permissions
return res.json({
continue_on: '/example-redirect',
});
}
שדות
ה-RP יכול לציין את פרטי המשתמש (כל שילוב של שם, כתובת אימייל ותמונת פרופיל) שהוא צריך שה-IdP ישתף איתו. המידע המבוקש ייכלל בממשק המשתמש של הגילוי הנאות בתיבת הדו-שיח של FedCM. אם המשתמש יבחר להיכנס לחשבון, יוצג לו הודעה על כך ש-idp.example
ישתף את המידע המבוקש עם rp.example
.
כדי להשתמש בתכונה 'שדות', RP צריך להוסיף מערך fields
בקריאה ל-navigator.credentials.get()
. השדות יכולים להכיל כל שילוב של name
, email
ו-picture
. בעתיד נוכל להרחיב את האפשרויות האלה כך שיכללו ערכים נוספים.
בקשה עם fields
תיראה כך:
let { token } = await navigator.credentials.get({
identity: {
providers: [{
// RP requests the IdP to share only user email and profile picture
fields: [ 'email', 'picture'],
clientId: '1234',
configURL: 'https://idp.example/fedcm.json',
},
}
});
הדפדפן יתרגם אותו באופן אוטומטי לבקשת HTTP לנקודת הקצה של טענת הנכוֹנוּת של הזהות, שכוללת את הפרמטר fields
שצוין על ידי RP, עם השדות שהדפדפן חשף למשתמש בפרמטר disclosure_shown_for
. מטעמי תאימות לאחור, הדפדפן ישלח גם את הערך disclosure_text_shown=true
אם טקסט הגילוי הנאות הוצג והשדות המבוקשים כוללים את כל שלושת השדות: 'name'
, 'email'
ו-'picture'
.
POST /id_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
// The RP only requested to share email and picture. The browser will send `disclosure_text_shown=false`, as the 'name' field value is missing
account_id=123&client_id=client1234&disclosure_text_shown=false&fields=email,picture&disclosure_shown_for=email,picture
אם fields
הוא מערך ריק, סוכן המשתמש ידלג על ממשק המשתמש של הגילוי הנאות.
זה קורה גם אם התגובה מנקודת הקצה accounts לא מכילה מזהה לקוח שתואם ל-RP ב-approved_clients
.
במקרה כזה, הערך של disclosure_text_shown
שנשלח אל נקודת הקצה של טענת הנכוֹנוּת של הזהות הוא false בגוף ה-HTTP:
POST /id_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=234234&disclosure_text_shown=false
הצגת הודעת שגיאה
לפעמים, יכול להיות שה-IdP לא יוכל להנפיק אסימון מסיבות לגיטימיות, למשל אם הלקוח לא מורשה או שהשרת לא זמין באופן זמני. אם ה-IdP מחזיר תשובה מסוג 'שגיאה', ה-RP יכול לזהות אותה ו-Chrome יכול להציג למשתמש את ממשק המשתמש של הדפדפן עם פרטי השגיאה שסופקו על ידי ה-IdP.
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;
}
אימות מחדש אוטומטי של משתמשים אחרי האימות הראשוני
אימות מחדש אוטומטי ב-FedCM (בקיצור 'אימות מחדש אוטומטי') מאפשר למשתמשים לבצע אימות מחדש באופן אוטומטי כשהם חוזרים אחרי האימות הראשוני באמצעות FedCM. 'אימות ראשוני' כאן פירושו שהמשתמש יוצר חשבון או נכנס לאתר של RP על ידי הקשה על הלחצן 'המשך בתור…' בתיבת הדו-שיח של FedCM לכניסה בפעם הראשונה באותו מופיע בדפדפן.
חוויית המשתמש המפורשת הגיונית לפני שהמשתמש יוצר את החשבון המאוחד כדי למנוע מעקב (אחד מהיעדים העיקריים של FedCM), אבל היא מסורבלת ללא צורך אחרי שהמשתמש עובר אותה פעם אחת: אחרי שהמשתמש מעניק הרשאה לאפשר תקשורת בין RP ל-IdP, אין תועלת לפרטיות או לאבטחה באכיפת אישור מפורש נוסף של המשתמש לגבי משהו שכבר אישר בעבר.
כשמפעילים אימות חוזר אוטומטי, הדפדפן משנה את ההתנהגות שלו בהתאם לאפשרות שציינתם עבור mediation
בזמן הקריאה ל-navigator.credentials.get()
.
const cred = await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/fedcm.json',
clientId: '1234',
}],
},
mediation: 'optional', // this is the default
});
// `isAutoSelected` is `true` if auto-reauthn was performed.
const isAutoSelected = cred.isAutoSelected;
השדה mediation
הוא מאפיין ב-Credential Management API, והוא פועל באותו אופן כמו ב-PasswordCredential וב-FederatedCredential, ויש לו תמיכה חלקית גם ב-PublicKeyCredential. המאפיין יכול לקבל את ארבעת הערכים הבאים:
'optional'
(ברירת המחדל): אימות מחדש אוטומטי אם אפשר, נדרש תהליך בחירת רשת אם לא. מומלץ לבחור באפשרות הזו בדף הכניסה.'required'
: תמיד נדרש תהליך בחירת רשת כדי להמשיך, למשל, לחיצה על הלחצן 'המשך' בממשק המשתמש. בוחרים באפשרות הזו אם המשתמשים אמורים להעניק הרשאה במפורש בכל פעם שהם צריכים לעבור אימות.'silent'
: אימות מחדש אוטומטי אם אפשר, כשל שקט ללא צורך בתהליך בחירת רשת אם לא. מומלץ לבחור באפשרות הזו בדפים שאינם דף הכניסה הייעודי, אבל שבהם אתם רוצים שהמשתמשים יישארו מחוברים – לדוגמה, דף פריט באתר של חברת משלוחים או דף כתבה באתר חדשות.'conditional'
: משמש ל-WebAuthn ולא זמין כרגע ל-FedCM.
כשמבצעים את הקריאה הזו, האימות מחדש האוטומטי מתבצע בתנאים הבאים:
- אפשר להשתמש ב-FedCM. לדוגמה, המשתמש לא השבית את FedCM ברמת הארגון או ברמת RP בהגדרות.
- המשתמש השתמש רק בחשבון אחד עם FedCM API כדי להיכנס לאתר בדפדפן הזה.
- המשתמש נכנס ל-IdP באמצעות החשבון הזה.
- האימות מחדש האוטומטי לא התרחש ב-10 הדקות האחרונות.
- ה-RP לא קרא ל-
navigator.credentials.preventSilentAccess()
אחרי הכניסה הקודמת.
כשהתנאים האלה מתקיימים, המערכת מנסה לאמת מחדש את המשתמש באופן אוטומטי ברגע שמפעילים את navigator.credentials.get()
של FedCM.
כשהערך הוא mediation: optional
, יכול להיות שהאימות מחדש האוטומטי לא יהיה זמין מסיבות שידועות רק לדפדפן. ה-RP יכול לבדוק אם האימות מחדש האוטומטי מתבצע על ידי בדיקת המאפיין isAutoSelected
.
כך תוכלו להעריך את ביצועי ה-API ולשפר את חוויית המשתמש בהתאם.
בנוסף, כשהיא לא זמינה, יכול להיות שהמשתמש יתבקש להיכנס באמצעות תהליך בחירת רשת מפורש על ידי המשתמש, שהוא תהליך עם mediation: required
.
אכיפת תהליך בחירת הרשת באמצעות preventSilentAccess()
אימות מחדש אוטומטי של משתמשים מיד אחרי שהם יוצאים מהחשבון לא יספק חוויית משתמש טובה במיוחד. לכן, ב-FedCM יש תקופת שקט של 10 דקות אחרי אימות מחדש אוטומטי כדי למנוע את ההתנהגות הזו. כלומר, האימות מחדש האוטומטי מתבצע לכל היותר פעם ב-10 דקות, אלא אם המשתמש נכנס שוב לחשבון תוך 10 דקות. ה-RP צריך לבצע קריאה ל-navigator.credentials.preventSilentAccess()
כדי לבקש מהדפדפן להשבית את האימות האוטומטי מחדש כשמשתמש יוצא מה-RP באופן מפורש, למשל על ידי לחיצה על לחצן יציאה.
function signout() {
navigator.credentials.preventSilentAccess();
location.href = '/signout';
}
המשתמשים יכולים לבטל את ההסכמה לאימות מחדש אוטומטי בהגדרות
המשתמשים יכולים לבטל את ההסכמה לאימות מחדש אוטומטי בתפריט ההגדרות:
- ב-Chrome למחשב, עוברים אל
chrome://password-manager/settings
> כניסה אוטומטית. - ב-Chrome ל-Android, פותחים את הגדרות > מנהל הסיסמאות > מקישים על גלגל השיניים בפינה השמאלית העליונה > כניסה אוטומטית.
השבתת המתג מאפשרת למשתמש לבטל את ההסכמה להתנהגות של אימות אוטומטי. ההגדרה הזו מאוחסנת ומסונכרנת במכשירים השונים, אם המשתמש מחובר לחשבון Google במכונה של Chrome והסנכרון מופעל.
ניתוק ה-IdP מה-RP
אם משתמש נכנס בעבר ל-RP באמצעות ה-IdP דרך FedCM, הדפדפן שומר את הקשר באופן מקומי כרשימה של החשבונות המקושרים. ה-RP יכול ליזום ניתוק על ידי הפעלת הפונקציה IdentityCredential.disconnect()
. אפשר להפעיל את הפונקציה הזו ממסגרת RP ברמה העליונה. ה-RP צריך להעביר configURL
, את ה-clientId
שבו הוא משתמש ב-IdP ואת ה-accountHint
כדי לנתק את ה-IdP. הטיפים לחשבון יכולים להיות מחרוזת שרירותית, כל עוד נקודת הקצה לניתוק יכולה לזהות את החשבון. לדוגמה, כתובת אימייל או מזהה משתמש שלא בהכרח תואמים למזהה החשבון שסופק על ידי נקודת הקצה של רשימת החשבונות:
// Disconnect an IdP account 'account456' from the RP 'https://idp.com/'. This is invoked on the RP domain.
IdentityCredential.disconnect({
configURL: 'https://idp.com/config.json',
clientId: 'rp123',
accountHint: 'account456'
});
הפונקציה IdentityCredential.disconnect()
מחזירה Promise
. הבטחה זו עשויה להוביל להשלכת חריגה מהסיבות הבאות:
- המשתמש לא נכנס ל-RP באמצעות ה-IdP דרך FedCM.
- ה-API מופעל מתוך iframe ללא מדיניות הרשאות של FedCM.
- configURL לא תקין או שחסר בו נקודת הקצה לניתוק.
- בדיקת Content Security Policy (CSP) נכשלת.
- יש בקשה לניתוק בהמתנה.
- המשתמש השבית את FedCM בהגדרות הדפדפן.
כשנקודת הקצה לניתוק של ה-IdP מחזירה תשובה, ה-RP וה-IdP מנותקים בדפדפן וההבטחה מתקבלת. המזהה של החשבונות שנפרדו מפורט בתגובה מנקודת הקצה לניתוק.