איך משתמשים ב-FedCM לאיחוד שירותי אימות הזהות תוך שמירה על פרטיות
FedCM (ניהול מאוחד של פרטי כניסה) הוא גישה לשמירה על הפרטיות בשירותי זהות מאוחדים (כמו 'כניסה באמצעות…'), שבה משתמשים יכולים להתחבר לאתרים בלי לשתף את המידע האישי שלהם עם שירות הזהות או עם האתר.
מידע נוסף על תרחישים לדוגמה, תהליכי משתמש ורשימת משימות ל-API זמין במבוא ל-FedCM API.
סביבת הפיתוח של FedCM
כדי להשתמש ב-FedCM, צריך הקשר מאובטח (HTTPS או localhost) גם ב-IdP וגם ב-RP ב-Chrome.
ניפוי באגים בקוד ב-Chrome ל-Android
הגדרה והפעלה של שרת באופן מקומי כדי לנפות באגים בקוד של FedCM. אפשר לגשת לשרת הזה ב-Chrome במכשיר Android שמחובר באמצעות כבל USB עם העברת יציאות.
אפשר להשתמש בכלי הפיתוח במחשב כדי לנפות באגים ב-Chrome ב-Android. לשם כך, פועלים לפי ההוראות במאמר ניפוי באגים מרחוק במכשירי Android.
חסימת קובצי cookie של צד שלישי ב-Chrome
אתם יכולים לבדוק איך FedCM פועל ללא קובצי Cookie של צד שלישי ב-Chrome לפני שהוא יופעל בפועל.
כדי לחסום קובצי Cookie של צד שלישי, משתמשים במצב פרטי או בוחרים באפשרות 'חסימת קובצי Cookie של צד שלישי' בהגדרות במחשב בכתובת chrome://settings/cookies
, או בנייד: עוברים אל הגדרות > הגדרות אתר > קובצי Cookie.
שימוש ב-FedCM API
כדי לשלב את FedCM, יוצרים קובץ ידוע, קובץ תצורה ונקודות קצה לרשימת החשבונות, להנפקת טענות נכוֹנוּת ולמטא-נתונים של הלקוח (אופציונלי).
משם, FedCM חושף ממשקי API של JavaScript שבהם ספקי ה-RP יכולים להשתמש כדי להיכנס לחשבון ב-IdP.
יצירת קובץ well-known
כדי למנוע משירותי מעקב לנצל לרעה את ה-API, צריך להציג קובץ well-known מ-/.well-known/web-identity
של eTLD+1 של ה-IdP.
לדוגמה, אם נקודות הקצה של ה-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"]
}
קובץ ה-JSON חייב להכיל את המאפיין provider_urls
עם מערך של כתובות URL של קובץ תצורה של IdP, שאפשר לציין כחלק מנתיב של configURL
ב-navigator.credentials.get
על ידי RPs. מספר מחרוזות כתובות ה-URL במערך מוגבל לאחת, אבל זה עשוי להשתנות בהתאם למשוב שלכם בעתיד.
יצירת קובץ תצורה ונקודות קצה של 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;
מציינים כתובת URL מלאה של המיקום של קובץ התצורה של ה-IdP כ-configURL
. כשnavigator.credentials.get()
נקרא ב-RP, הדפדפן מאחזר את קובץ התצורה באמצעות בקשת GET
ללא הכותרת Origin
או הכותרת Referer
. לבקשה אין קובצי cookie והיא לא עוקבת אחרי הפניות אוטומטיות.
כך אפשר למנוע מה-IdP לדעת מי שלח את הבקשה ואיזה RP מנסה להתחבר. לדוגמה:
GET /config.json HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity
הדפדפן מצפה לתגובת JSON מה-IdP, שכוללת את המאפיינים הבאים:
נכס | תיאור |
---|---|
accounts_endpoint (חובה) |
כתובת ה-URL של נקודת הקצה (endpoint) של החשבונות. |
ֶ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 (אופציונלי) |
אפשרות מיתוג שמגדירה את אובייקט הסמל שמוצג בתיבת הדו-שיח של הכניסה. אובייקט הסמל הוא מערך עם שני פרמטרים:
|
ה-RP יכול לשנות את המחרוזת בממשק המשתמש של תיבת הדו-שיח של FedCM באמצעות הערך identity.context
של navigator.credentials.get()
כדי להתאים להקשרי אימות מוגדרים מראש. המאפיין האופציונלי יכול להיות אחד מהערכים "signin"
(ברירת המחדל), "signup"
,
"use"
או "continue"
.
זוהי דוגמה לגוף תגובה מה-IdP:
{
"accounts_endpoint": "/accounts.php",
"client_metadata_endpoint": "/client_metadata.php",
"id_assertion_endpoint": "/assertion.php",
"disconnect_endpoint": "/disconnect.php",
"login_url": "/login",
"branding": {
"background_color": "green",
"color": "#FFEEAA",
"icons": [{
"url": "https://idp.example/icon.ico",
"size": 25
}]
}
}
אחרי שהדפדפן מאחזר את קובץ התצורה, הוא שולח בקשות נוספות לנקודות הקצה של ה-IdP:
נקודת הקצה של חשבונות
נקודת הקצה של החשבונות ב-IdP מחזירה רשימה של חשבונות שבהם המשתמש נכנס ל-IdP. אם ה-IdP תומך בכמה חשבונות, נקודת הקצה הזו תחזיר את כל החשבונות שנכנסו.
הדפדפן שולח בקשת GET
עם קובצי cookie עם SameSite=None
, אבל בלי פרמטר client_id
, בלי הכותרת Origin
ובלי הכותרת Referer
. כך אפשר למנוע מה-IdP לדעת לאיזה RP המשתמש מנסה להיכנס. לדוגמה:
GET /accounts.php 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 כדי לסנן את החשבונות. |
דוגמה לגוף התגובה:
{
"accounts": [{
"id": "1234",
"given_name": "John",
"name": "John Doe",
"email": "john_doe@idp.example",
"picture": "https://idp.example/profile/123",
"approved_clients": ["123", "456", "789"],
"login_hints": ["demo1", "demo1@idp.example"]
}, {
"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", "demo2@idp.example"],
"domain_hints": ["corp.example"]
}]
}
אם המשתמש לא מחובר לחשבון, יש להשיב עם HTTP 401 (לא מורשה).
רשימת החשבונות שמוחזרת נצרכת על ידי הדפדפן ולא תהיה זמינה ל-RP.
נקודת קצה של מטא-נתונים של לקוח
נקודת הקצה של המטא-נתונים של הלקוח ב-IdP מחזירה את המטא-נתונים של הצד הנסמך, כמו מדיניות הפרטיות ותנאי השירות של ה-RP. ספקי ה-RP צריכים לספק ל-IdP מראש קישורים למדיניות הפרטיות ולתנאים ולהגבלות שלהם. הקישורים האלה מוצגים בתיבת הדו-שיח של הכניסה כשהמשתמש עדיין לא נרשם ב-RP דרך ה-IdP.
הדפדפן שולח בקשת GET
באמצעות client_id
navigator.credentials.get
ללא קובצי cookie. לדוגמה:
GET /client_metadata.php?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. |
הדפדפן מצפה לקבל תגובת JSON מנקודת הקצה:
{
"privacy_policy_url": "https://rp.example/privacy_policy.html",
"terms_of_service_url": "https://rp.example/terms_of_service.html",
}
הדפדפן משתמש במטא-נתוני הלקוח שהוחזרו, והם לא יהיו זמינים ל-RP.
נקודת קצה לאישור זהות
נקודת הקצה של טענת הנכוֹנוּת (assertion) של הזהות ב-IdP מחזירה טענת נכוֹנוּת למשתמש המחובר.
כשהמשתמש נכנס לאתר של RP באמצעות קריאה ל-navigator.credentials.get()
, הדפדפן שולח בקשת POST
עם קובצי cookie עם SameSite=None
וסוג תוכן application/x-www-form-urlencoded
לנקודת הקצה הזו עם הפרטים הבאים:
נכס | תיאור |
---|---|
client_id (חובה) |
מזהה הלקוח של RP. |
account_id (חובה) |
המזהה הייחודי של המשתמש שנכנס לחשבון. |
ֶnonce (אופציונלי) |
המזהה החד-פעמי של הבקשה, שסופק על ידי ה-RP. |
disclosure_text_shown |
הפונקציה מחזירה מחרוזת של "true" או "false" (במקום ערך בוליאני). התוצאה היא "false" אם טקסט הגילוי הנאות לא הוצג. המצב הזה מתרחש כאשר מזהה הלקוח של RP נכלל ברשימת המאפיינים approved_clients בתגובה מנקודת הקצה accounts, או אם הדפדפן זיהה רגע הרשמה בעבר ללא approved_clients . |
is_auto_selected |
אם מתבצעת אימות חוזר אוטומטי ב-RP, הערך של is_auto_selected הוא "true" . אחרת "false" . כך אפשר לתמוך בתכונות נוספות שקשורות לאבטחה. לדוגמה, יכול להיות שחלק מהמשתמשים יעדיפו רמת אבטחה גבוהה יותר שמחייבת התערבות מפורשת של המשתמש באימות. אם IdP מקבל בקשה לאסימון ללא תהליך בחירת הרשת, הוא יכול לטפל בבקשה בצורה שונה. לדוגמה, אפשר להחזיר קוד שגיאה כדי שה-RP יוכל לקרוא שוב ל-FedCM API עם mediation: required . |
דוגמה לכותרת HTTP:
POST /assertion.php HTTP/1.1
Host: accounts.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=Ct60bD&disclosure_text_shown=true&is_auto_selected=true
כשהבקשה תתקבל, השרת צריך:
- משיבים לבקשה באמצעות CORS (שיתוף משאבים בין מקורות).
- מוודאים שהבקשה מכילה כותרת HTTP מסוג
Sec-Fetch-Dest: webidentity
. - המערכת תשווה את הכותרת
Origin
למקור ה-RP שנקבע על ידיclient_id
. אם הם לא תואמים, דוחים אותם. - מתאימים את
account_id
למזהה של החשבון שכבר נכנסתם אליו. אם הן לא תואמות, דוחים את הבקשה. - משיבים עם אסימון. אם הבקשה נדחית, יש להשיב עם תגובת שגיאה.
האופן שבו האסימון מונפק נתון לשיקול דעתו של ה-IdP, אבל באופן כללי הוא חתום על ידי מידע כמו מזהה החשבון, מזהה הלקוח, מקור המנפיק, nonce
, כדי ש-RP יוכל לאמת שהאסימון הוא אמיתי.
הדפדפן מצפה לתגובת JSON שכוללת את המאפיין הבא:
נכס | תיאור |
---|---|
token (חובה) |
אסימון הוא מחרוזת שמכילה הצהרות על האימות. |
{
"token": "***********"
}
הדפדפן מעביר את האסימון המוחזר ל-RP, כדי שה-RP יוכל לאמת את האימות.
החזרת הודעת שגיאה
ה-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"
}
}
ניתוק נקודת הקצה
כשמפעילים את IdentityCredential.disconnect()
, הדפדפן שולח בקשת POST
חוצת-מקור עם קובצי cookie עם SameSite=None
וסוג תוכן של application/x-www-form-urlencoded
לנקודת הקצה הזו לניתוק, עם הפרטים הבאים:
נכס | תיאור |
---|---|
account_hint |
רמז לחשבון ה-IdP. |
client_id |
מזהה הלקוח של RP. |
POST /disconnect.php 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, צריך להעביר מחרוזת שלא תואמת למספר חשבון כלשהו, למשל "*"
.
כתובת URL לכניסה
באמצעות 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
. מצב ברירת המחדל הוא unknown
.
כדי לסמן שהמשתמש מחובר, שולחים כותרת HTTP Set-Login: logged-in
בבקשת ניווט ברמה העליונה או בבקשה לשימוש במשאב משנה באותו אתר במקור של ה-IdP:
Set-Login: logged-in
לחלופין, אפשר לבצע קריאה ל-JavaScript API navigator.login.setStatus("logged-in")
ממקור ה-IdP בניווט ברמה העליונה:
navigator.login.setStatus("logged-in")
בקריאות האלה, סטטוס ההתחברות של המשתמש מתועד כ-logged-in
. כשסטטוס ההתחברות של המשתמש מוגדר ל-logged-in
, ה-RP שמפעיל את FedCM שולח בקשות לנקודת הקצה של החשבונות ב-IdP ומציג את החשבונות הזמינים למשתמש בתיבת הדו-שיח של FedCM.
כדי לסמן שהמשתמש התנתק מכל החשבונות שלו, שולחים את כותרת ה-HTTP Set-Login:
logged-out
בתפריט ברמה העליונה או בבקשה לשימוש במשאב משנה באותו אתר במקור של ה-IdP:
Set-Login: logged-out
לחלופין, אפשר לבצע קריאה ל-JavaScript API navigator.login.setStatus("logged-out")
ממקור ה-IdP בניווט ברמה העליונה:
navigator.login.setStatus("logged-out")
בקריאות האלה, סטטוס ההתחברות של המשתמש מתועד כ-logged-out
. כשסטטוס ההתחברות של המשתמש הוא logged-out
, הקריאה ל-FedCM נכשלת בשקט בלי לשלוח בקשה לנקודת הקצה של החשבונות ב-IdP.
הסטטוס unknown
מוגדר לפני שה-IdP שולח אות באמצעות ה-API של סטטוס הכניסה. הוספנו את Unknown
כדי להקל על המעבר, כי יכול להיות שמשתמש כבר נכנס ל-IdP כשה-API הזה נשלח. יכול להיות של-IdP לא תהיה הזדמנות להעביר את האות הזה לדפדפן עד להפעלה הראשונה של FedCM. במקרה כזה, Chrome שולח בקשה לנקודת הקצה לחשבונות של ה-IdP ומעדכן את הסטטוס על סמך התשובה מנקודת הקצה לחשבונות:
- אם נקודת הקצה מחזירה רשימה של חשבונות פעילים, מעדכנים את הסטטוס ל-
logged-in
ופותחים את תיבת הדו-שיח של FedCM כדי להציג את החשבונות האלה. - אם נקודת הקצה לא מחזירה חשבונות, מעדכנים את הסטטוס ל-
logged-out
ומכשילים את הקריאה ל-FedCM.
לאפשר למשתמש להיכנס לחשבון דרך תהליך כניסה דינמי
למרות ש-IdP ממשיך לעדכן את סטטוס ההתחברות של המשתמש בדפדפן, יכול להיות שהסנכרון לא יהיה תקין, למשל כשיפוג התוקף של הסשן. הדפדפן מנסה לשלוח בקשה עם פרטי כניסה לנקודת הקצה של החשבונות כשסטטוס ההתחברות הוא logged-in
, אבל השרת לא מחזיר חשבונות כי הסשן כבר לא זמין. בתרחיש כזה, הדפדפן יכול לאפשר למשתמש להיכנס באופן דינמי ל-IdP דרך חלון קופץ.
כניסה לצד הנסמך באמצעות ספק הזהויות
אחרי שההגדרות והנקודות הקצה של ה-IdP יהיו זמינות, ספקי ה-RP יוכלו לבצע קריאה ל-navigator.credentials.get()
כדי לבקש הרשאה למשתמשים להיכנס ל-RP באמצעות ה-IdP.
לפני שמפעילים את ה-API, צריך לוודא ש-FedCM זמין בדפדפן של המשתמש. כדי לבדוק אם FedCM זמין, צריך להוסיף את הקוד הזה להטמעת FedCM:
if ('IdentityCredential' in window) {
// If the feature is available, take action
}
כדי לבקש לאפשר למשתמשים להיכנס ל-IdP מה-RP, מבצעים את הפעולות הבאות, לדוגמה:
const credential = await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://accounts.idp.example/config.json',
clientId: '********',
nonce: '******'
}]
}
});
const { token } = credential;
הנכס providers
מקבל מערך של אובייקטים מסוג IdentityProvider
שיש להם את המאפיינים הבאים:
נכס | תיאור |
---|---|
configURL (חובה) |
הנתיב המלא של קובץ התצורה של ה-IdP. |
clientId (חובה) |
מזהה הלקוח של ה-RP, שהונפק על ידי ה-IdP. |
ֶnonce (אופציונלי) |
מחרוזת אקראית כדי לוודא שהתגובה תישלח עבור הבקשה הספציפית הזו. מניעת התקפות שחזור. |
ֶloginHint (אופציונלי) |
כשמציינים אחד מהערכים של login_hints שסופקו על ידי נקודות הקצה של החשבונות, בתיבת הדו-שיח של FedCM מוצג באופן סלקטיבי החשבון שצוין. |
ֶdomainHint (אופציונלי) |
אם מציינים אחד מהערכים של domain_hints שסופקו על ידי נקודות הקצה של החשבונות, בתיבת הדו-שיח של FedCM יוצג באופן סלקטיבי החשבון שצוין. |
הדפדפן מטפל בתרחישי השימוש של הרשמה וכניסה באופן שונה, בהתאם לנוכחות של approved_clients
בתגובה מנקודת הקצה של רשימת החשבונות. הדפדפן לא יציג את הטקסט של גילוי הנאות "To continue with ...." אם המשתמש כבר נרשם ל-RP.
סטטוס ההרשמה נקבע על סמך התנאים הבאים:
- אם השדה
approved_clients
כולל את השדהclientId
של ה-RP. - אם הדפדפן זוכר שהמשתמש כבר נרשם ל-RP.
כשה-RP קורא ל-navigator.credentials.get()
, מתבצעות הפעולות הבאות:
- הדפדפן שולח בקשות ומאחזר כמה מסמכים:
- קובץ ה-well-known וקובץ תצורה של IdP שמצהירים על נקודות קצה.
- רשימת חשבונות.
- אופציונלי: כתובות URL של מדיניות הפרטיות והתנאים וההגבלות של RP, שאוחזרו מנקודת הקצה של המטא-נתונים של הלקוח.
- בדפדפן מוצגת רשימת החשבונות שבהם המשתמש יכול להשתמש כדי להיכנס, וכן התנאים וההגבלות ומדיניות הפרטיות, אם הם זמינים.
- אחרי שהמשתמש בוחר חשבון שבו יתבצע הכניסה, נשלחת בקשה לנקודת הקצה של טענת הנכוֹנוּת של הזהות אל ה-IdP כדי לאחזר אסימון.
- ה-RP יכול לאמת את הטוקן כדי לאמת את המשתמש.
ספקי RP צפויים לתמוך בדפדפנים שלא תומכים ב-FedCM, ולכן המשתמשים אמורים להיות מסוגלים להשתמש בתהליך כניסה קיים שאינו של FedCM. עד שקובצי ה-Cookie של צד שלישי לא יהיו זמינים יותר בדפדפנים, לא אמורה להיות בעיה.
אחרי שהאסימון מאומת על ידי שרת ה-RP, ה-RP יכול לרשום את המשתמש או לאפשר לו להיכנס לחשבון ולהתחיל סשן חדש.
Login Hint API
אחרי שהמשתמש נכנס לחשבון, לפעמים הצד הנסמך (RP) מבקש מהמשתמש לבצע אימות מחדש. אבל יכול להיות שהמשתמש לא יודע באיזה חשבון הוא השתמש. אם ה-RP יכול לציין לאיזה חשבון להיכנס, יהיה קל יותר למשתמש לבחור חשבון.
כדי להציג חשבון ספציפי באופן סלקטיבי, חשבונות משתמשים מורשים יכולים להפעיל את navigator.credentials.get()
עם המאפיין loginHint
עם אחד מערכי login_hints
שאוחזר מנקודת הקצה של רשימת החשבונות, כפי שמוצג בדוגמת הקוד הבאה:
return await navigator.credentials.get({
identity: {
providers: [{
configURL: "https://idp.example/manifest.json",
clientId: "123",
nonce: nonce,
loginHint : "demo1@example.com"
}]
}
});
אם אין חשבונות שתואמים ל-loginHint
, בתיבת הדו-שיח של FedCM תוצג בקשה להתחברות, שמאפשרת למשתמש להתחבר לחשבון IdP שתואם לטיפת המידע שביקשה ה-RP. כשהמשתמש מקייש על ההנחיה, נפתח חלון קופץ עם כתובת ה-URL להתחברות שצוינה בקובץ התצורה. לאחר מכן, הקישור יתווספו לו פרמטרים של שאילתות של רמז להתחברות ורמז לדומיין.
Domain Hint API
יש מקרים שבהם ה-RP כבר יודע שרק חשבונות שמשויכים לדומיין מסוים מורשים להתחבר לאתר. המצב הזה נפוץ במיוחד בתרחישים ארגוניים שבהם הגישה לאתר מוגבלת לדומיין של הארגון. כדי לספק חוויית משתמש טובה יותר, FedCM API מאפשר ל-RP להציג רק את החשבונות שאפשר להשתמש בהם כדי להתחבר ל-RP. כך אפשר למנוע תרחישים שבהם משתמש מנסה להתחבר ל-RP באמצעות חשבון מחוץ לדומיין הארגוני, ורק מאוחר יותר מוצגת לו הודעת שגיאה (או שקט אם ההתחברות לא פעלה) כי לא נעשה שימוש בחשבון מהסוג הנכון.
כדי להציג באופן סלקטיבי רק חשבונות תואמים, שותפי ה-API יכולים להפעיל את navigator.credentials.get()
עם המאפיין domainHint
עם אחד מערכי domain_hints
שאוחזר מנקודת הקצה של רשימת החשבונות, כפי שמוצג בדוגמת הקוד הבאה:
return await navigator.credentials.get({
identity: {
providers: [{
configURL: "https://idp.example/manifest.json",
clientId: "abc",
nonce: nonce,
domainHint : "corp.example"
}]
}
});
אם אין חשבונות שתואמים ל-domainHint
, בתיבת הדו-שיח של FedCM תוצג בקשה להתחברות, שמאפשרת למשתמש להתחבר לחשבון IdP שתואם לטיפת המידע שביקשה ה-RP. כשהמשתמש מקייש על ההנחיה, נפתח חלון קופץ עם כתובת ה-URL להתחברות שצוינה בקובץ התצורה. לאחר מכן, הקישור יתווספו לו פרמטרים של שאילתות של רמז להתחברות ורמז לדומיין.
הצגת הודעת שגיאה
לפעמים, יכול להיות שה-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 מנותקים בדפדפן וההבטחה מתקבלת. המזהה של החשבונות שנפרדו מפורט בתגובה מנקודת הקצה לניתוק.
קריאה ל-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")
מידע נוסף על האופן שבו פועלת מדיניות ההרשאות זמין במאמר שליטה בתכונות הדפדפן באמצעות מדיניות ההרשאות.