یاد بگیرید که چگونه از FedCM برای فدراسیون حفظ حریم خصوصی استفاده کنید.
FedCM (مدیریت اعتبار فدرال) یک رویکرد حفظ حریم خصوصی برای خدمات هویتی فدرال (مانند "ورود به سیستم با...") است که در آن کاربران می توانند بدون به اشتراک گذاشتن اطلاعات شخصی خود با سرویس هویت یا سایت وارد سایت ها شوند.
برای کسب اطلاعات بیشتر در مورد موارد استفاده FedCM، جریان های کاربر و نقشه راه API ، مقدمه FedCM API را بررسی کنید.
محیط توسعه FedCM
برای استفاده از FedCM به یک زمینه امن (HTTPS یا localhost) هم در IdP و هم در RP در کروم نیاز دارید.
کد اشکال زدایی در کروم در اندروید
برای رفع اشکال کد FedCM خود، سروری را به صورت محلی تنظیم و اجرا کنید. میتوانید در Chrome در دستگاه Android متصل شده با استفاده از کابل USB با پورت فوروارد به این سرور دسترسی داشته باشید .
میتوانید از DevTools در دسکتاپ برای اشکالزدایی Chrome در Android با پیروی از دستورالعملهای Remote Debug دستگاههای Android استفاده کنید.
کوکیهای شخص ثالث را در Chrome مسدود کنید
میتوانید قبل از اجرای واقعی FedCM بدون کوکیهای شخص ثالث در Chrome آزمایش کنید.
برای مسدود کردن کوکیهای شخص ثالث، از حالت ناشناس استفاده کنید یا «مسدود کوکیهای شخص ثالث» را در تنظیمات دسکتاپ خود در chrome://settings/cookies
یا در تلفن همراه با رفتن به تنظیمات > تنظیمات سایت > کوکیها انتخاب کنید.
از FedCM API استفاده کنید
شما با ایجاد یک فایل شناخته شده ، فایل پیکربندی و نقاط پایانی برای لیست حساب ها ، صدور ادعا و به صورت اختیاری ابرداده مشتری ، با FedCM ادغام می شوید.
از آنجا، FedCM API های جاوا اسکریپت را نشان می دهد که RP ها می توانند برای ورود به سیستم با IdP از آنها استفاده کنند.
یک فایل شناخته شده ایجاد کنید
برای جلوگیری از سوء استفاده ردیابها از API ، یک فایل شناخته شده باید از /.well-known/web-identity
eTLD+1 IdP ارائه شود.
به عنوان مثال، اگر نقاط پایانی IdP تحت https://accounts.idp.example/
ارائه می شوند، باید یک فایل شناخته شده در https://idp.example/.well-known/web-identity
و همچنین یک فایل ارائه دهند. فایل پیکربندی IdP . در اینجا یک نمونه از محتوای فایل معروف است:
{
"provider_urls": ["https://accounts.idp.example/config.json"]
}
فایل JSON باید دارای ویژگی provider_urls
با آرایهای از URLهای فایل پیکربندی IdP باشد که میتواند به عنوان بخشی از مسیر configURL
در navigator.credentials.get
توسط RPها مشخص شود . تعداد رشتههای 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
واکشی می کند. درخواست کوکی ندارد و از تغییر مسیرها پیروی نمی کند. این به طور موثری از IdP جلوگیری میکند که بفهمد چه کسی درخواست را انجام داده و کدام RP را در تلاش برای اتصال است. به عنوان مثال:
GET /config.json HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity
مرورگر یک پاسخ JSON از IdP انتظار دارد که شامل ویژگی های زیر است:
اموال | توضیحات |
---|---|
accounts_endpoint (الزامی) | URL برای نقطه پایانی حسابها . |
client_metadata_endpoint (اختیاری) | URL برای نقطه پایانی فراداده مشتری . |
id_assertion_endpoint (الزامی) | URL برای نقطه پایانی ادعای شناسه . |
disconnect (اختیاری) | URL برای نقطه پایانی قطع ارتباط . |
login_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 با استفاده از مقدار navigator.credentials.get()
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
را با کوکیهایی با 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
باشد. - کوکیهای جلسه را با شناسههای حسابهایی که قبلاً وارد سیستم شدهاند مطابقت دهید.
- با لیست حساب ها پاسخ دهید.
مرورگر انتظار پاسخ 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
بدون کوکی ارسال می کند. به عنوان مثال:
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 در دسترس نخواهد بود.
نقطه پایان ادعای شناسه
نقطه پایانی ادعای شناسه IdP یک ادعا را برای کاربر واردشده به سیستم باز میگرداند. هنگامی که کاربر با استفاده از فراخوان navigator.credentials.get()
وارد یک وب سایت RP می شود، مرورگر یک درخواست POST
با کوکی هایی با SameSite=None
و یک نوع محتوا از application/x-www-form-urlencoded
به این نقطه پایانی ارسال می کند. اطلاعات زیر:
اموال | توضیحات |
---|---|
client_id (الزامی) | شناسه مشتری RP. |
account_id (الزامی) | شناسه منحصر به فرد کاربر در حال ورود به سیستم. |
nonce (اختیاری) | درخواست هیچ، ارائه شده توسط RP. |
disclosure_text_shown | نتیجه در یک رشته "true" یا "false" (به جای یک بولی). اگر متن افشا نشان داده نشود، نتیجه "false" است. این زمانی اتفاق میافتد که شناسه مشتری RP در لیست ویژگیهای approved_clients پاسخ از نقطه پایانی حسابها گنجانده شده باشد یا اگر مرورگر در گذشته یک لحظه ثبتنام را در غیاب 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
همچنین می تواند یک پاسخ "خطا" را برگرداند که دارای دو فیلد اختیاری است:
-
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
متقاطع را با کوکی هایی با 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 به مرورگر پاسخ دهید.
یک نمونه پاسخ JSON payload به این صورت است:
{
"account_id": "account456"
}
در عوض، اگر IdP بخواهد مرورگر همه حسابهای مرتبط با RP را قطع کند، رشتهای را ارسال کنید که با هیچ شناسه حسابی مطابقت ندارد، به عنوان مثال "*"
.
URL ورود
با Login Status API ، IdP باید وضعیت ورود کاربر را به مرورگر اطلاع دهد. با این حال، وضعیت ممکن است هماهنگ نباشد، مانند زمانی که جلسه منقضی شود . در چنین سناریویی، مرورگر می تواند به صورت پویا به کاربر اجازه دهد از طریق URL صفحه ورود مشخص شده با login_url
فایل پیکربندی idp وارد IdP شود.
همانطور که در تصویر زیر نشان داده شده است، کادر گفتگوی FedCM پیامی را نشان می دهد که ورود به سیستم را پیشنهاد می کند.
هنگامی که کاربر روی دکمه Continue کلیک می کند، مرورگر یک پنجره بازشو برای صفحه ورود IdP باز می کند.
گفتگو یک پنجره معمولی مرورگر است که کوکی های شخص اول دارد. هر آنچه در گفتگو اتفاق می افتد به IdP بستگی دارد و هیچ دسته پنجره ای برای درخواست ارتباط متقابل به صفحه RP در دسترس نیست. پس از ورود کاربر به سیستم، IdP باید:
- هدر
Set-Login: logged-in
ارسال کنید یا باnavigator.login.setStatus("logged-in")
API تماس بگیرید تا به مرورگر اطلاع دهید که کاربر وارد سیستم شده است. - برای بستن دیالوگ،
IdentityProvider.close()
را فراخوانی کنید.
مرورگر را در مورد وضعیت ورود کاربر در ارائه دهنده هویت مطلع کنید
Login Status API مکانیزمی است که در آن یک وب سایت، به ویژه یک IdP، وضعیت ورود کاربر را در IdP به مرورگر اطلاع می دهد. با این API، مرورگر میتواند درخواستهای غیرضروری را به IdP کاهش دهد و حملات احتمالی زمانبندی را کاهش دهد.
IdP ها می توانند با ارسال یک هدر HTTP یا با فراخوانی یک 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 با استفاده از Login Status API تنظیم می شود. Unknown
برای انتقال بهتر معرفی شد، زیرا ممکن است کاربر از قبل در هنگام ارسال این API وارد IdP شده باشد. ممکن است تا زمانی که FedCM برای اولین بار فراخوانی می شود، IdP فرصتی برای ارسال این سیگنال به مرورگر نداشته باشد. در این مورد، Chrome به نقطه پایانی حسابهای IdP درخواست میکند و وضعیت را براساس پاسخ نقطه پایانی حسابها بهروزرسانی میکند:
- اگر نقطه پایانی فهرستی از حسابهای فعال را برمیگرداند، وضعیت را به
logged-in
بهروزرسانی کنید و کادر گفتگوی FedCM را برای نمایش آن حسابها باز کنید. - اگر نقطه پایانی هیچ حسابی برگرداند، وضعیت را به
logged-out
بهروزرسانی کنید و تماس FedCM ناموفق باشد.
به کاربر اجازه دهید از طریق یک جریان ورود پویا وارد سیستم شود
حتی اگر IdP وضعیت ورود کاربر به مرورگر را به اطلاع میرساند، ممکن است مانند زمانی که جلسه منقضی میشود، هماهنگ نباشد. هنگامی که وضعیت ورود به سیستم logged-in
است، مرورگر سعی میکند یک درخواست اعتبارسنجی را به نقطه پایانی حسابها ارسال کند، اما سرور هیچ حسابی برمیگرداند زیرا جلسه دیگر در دسترس نیست. در چنین سناریویی، مرورگر میتواند به صورت پویا به کاربر اجازه دهد از طریق یک پنجره بازشو به IdP وارد شود .
با ارائه دهنده هویت به طرف متکی وارد شوید
هنگامی که پیکربندی و نقاط پایانی IdP در دسترس هستند، RP ها می توانند با فراخوانی navigator.credentials.get()
درخواست کنند تا کاربران بتوانند با IdP وارد RP شوند.
قبل از تماس با 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
در پاسخ از نقطه پایانی فهرست حسابها، موارد استفاده از ثبت نام و ورود به سیستم را متفاوت مدیریت میکند. اگر کاربر قبلاً در RP ثبت نام کرده باشد، مرورگر متن افشای «برای ادامه با ...» را نمایش نمی دهد.
وضعیت ثبت نام بر اساس رعایت یا عدم رعایت شرایط زیر تعیین می شود:
- اگر
approved_clients
شاملclientId
RP باشد. - اگر مرورگر به خاطر آورد که کاربر قبلاً در RP ثبت نام کرده است.
هنگامی که RP navigator.credentials.get()
را فرا می خواند، فعالیت های زیر انجام می شود:
- مرورگر درخواست ها را ارسال می کند و چندین سند را واکشی می کند:
- فایل شناخته شده و یک فایل پیکربندی IdP که نقاط پایانی را اعلام می کند.
- لیست حساب ها
- اختیاری: نشانیهای وب برای خطمشی رازداری و شرایط خدمات RP، بازیابی شده از نقطه پایانی فراداده مشتری .
- مرورگر فهرستی از حسابهایی را که کاربر میتواند برای ورود به سیستم از آنها استفاده کند، و همچنین شرایط خدمات و خطمشی رازداری در صورت وجود را نمایش میدهد.
- هنگامی که کاربر حسابی را برای ورود به سیستم انتخاب کرد، یک درخواست به نقطه پایانی ادعای ID برای بازیابی یک نشانه به IdP ارسال می شود.
- RP می تواند توکن را برای احراز هویت کاربر تأیید کند.
انتظار می رود RP ها از مرورگرهایی پشتیبانی کنند که از FedCM پشتیبانی نمی کنند، بنابراین کاربران باید بتوانند از یک فرآیند ورود به سیستم موجود و غیر FedCM استفاده کنند. تا زمانی که کوکی های شخص ثالث دیگر در مرورگرها در دسترس نباشند، این باید بدون مشکل باقی بماند.
هنگامی که رمز توسط سرور RP تأیید شد، RP ممکن است کاربر را ثبت کند یا به او اجازه ورود به سیستم و شروع یک جلسه جدید را بدهد.
Login Hint API
پس از ورود کاربر به سیستم، گاهی اوقات طرف متکی (RP) از کاربر می خواهد که احراز هویت مجدد را انجام دهد. اما کاربر ممکن است مطمئن نباشد که از کدام حساب استفاده کرده است. اگر 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 وارد شود، اما بعداً با یک پیام خطا (یا در مواردی که ورود کار نمی کند خاموش شود) به دلیل استفاده نکردن از نوع درست حساب، به او نمایش داده می شود.
RP ها می توانند به طور انتخابی فقط حساب های منطبق را با فراخوانی 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 می تواند آن را دریافت کند، همچنین کروم با نشان دادن رابط کاربری مرورگر با اطلاعات خطای ارائه شده توسط 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 دوباره به طور خودکار احراز هویت شوند. "تأیید هویت اولیه" در اینجا به این معنی است که کاربر با ضربه زدن روی دکمه "ادامه به عنوان..." در گفتگوی ورود به سیستم FedCM برای اولین بار در همان نمونه مرورگر، یک حساب ایجاد می کند یا به وب سایت RP وارد می شود.
در حالی که تجربه کاربری صریح قبل از ایجاد حساب فدرال توسط کاربر برای جلوگیری از ردیابی (که یکی از اهداف اصلی FedCM است) منطقی است، پس از اینکه کاربر یک بار آن را گذرانده است، غیرضروری دست و پا گیر است: پس از اعطای مجوز به کاربر برای اجازه دادن به آن. ارتباط بین RP و IdP، هیچ مزیتی برای حفظ حریم خصوصی یا امنیتی برای اعمال تأیید صریح کاربر دیگر برای چیزی که قبلاً تأیید کرده است وجود ندارد.
با احراز هویت مجدد خودکار، مرورگر رفتار خود را بسته به گزینه ای که هنگام فراخوانی navigator.credentials.get()
برای mediation
تعیین می کنید تغییر می دهد.
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()
را فراخوانی نکرده است.
هنگامی که این شرایط برآورده می شود، به محض فراخوانی FedCM navigator.credentials.get()
تلاش برای احراز هویت مجدد خودکار کاربر شروع می شود.
هنگامی که mediation: optional
، احراز هویت مجدد خودکار ممکن است به دلایلی که فقط مرورگر می داند در دسترس نباشد . RP می تواند با بررسی ویژگی isAutoSelected
بررسی کند که آیا احراز هویت مجدد خودکار انجام می شود یا خیر.
این برای ارزیابی عملکرد API و بهبود UX بر این اساس مفید است. همچنین، هنگامی که در دسترس نیست، ممکن است از کاربر خواسته شود با میانجیگری صریح کاربر وارد سیستم شود، که یک جریان با mediation: required
.
اجرای میانجیگری با preventSilentAccess()
احراز هویت مجدد خودکار کاربران بلافاصله پس از خروج از سیستم، تجربه کاربری بسیار خوبی را ایجاد نمی کند. به همین دلیل است که FedCM برای جلوگیری از این رفتار، یک دوره 10 دقیقهای سکوت پس از احراز هویت مجدد خودکار دارد. این بدان معناست که احراز هویت مجدد خودکار حداکثر هر 10 دقیقه یک بار اتفاق میافتد مگر اینکه کاربر در عرض 10 دقیقه دوباره وارد سیستم شود. RP باید navigator.credentials.preventSilentAccess()
را فراخوانی کند تا صراحتاً از مرورگر درخواست کند تا زمانی که کاربر بطور صریح از RP خارج می شود، مثلاً با کلیک کردن روی دکمه خروج، احراز هویت مجدد خودکار را غیرفعال کند.
function signout() {
navigator.credentials.preventSilentAccess();
location.href = '/signout';
}
کاربران می توانند از احراز هویت مجدد خودکار در تنظیمات انصراف دهند
کاربران می توانند از منوی تنظیمات از احراز هویت مجدد خودکار انصراف دهند:
- در کروم دسکتاپ، به
chrome://password-manager/settings
> ورود خودکار به سیستم بروید. - در Android Chrome، تنظیمات > مدیریت رمز عبور > روی چرخ دنده در گوشه بالا سمت راست > ورود خودکار ضربه بزنید.
با غیرفعال کردن جابهجایی، کاربر میتواند با هم از رفتار احراز هویت مجدد خودکار انصراف دهد. اگر کاربر در نمونه کروم وارد حساب Google شده باشد و همگامسازی فعال باشد، این تنظیم در همه دستگاهها ذخیره و همگامسازی میشود.
IdP را از RP جدا کنید
اگر کاربر قبلاً با استفاده از IdP از طریق FedCM وارد RP شده باشد، این رابطه توسط مرورگر به صورت محلی به عنوان فهرست حسابهای متصل حفظ میشود. 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
ای را برمی گرداند. این قول ممکن است به دلایل زیر استثناء کند:
- کاربر با استفاده از IDP از طریق FEDCM وارد RP نشده است.
- API از درون یک IFRAME بدون سیاست مجوزهای FEDCM فراخوانی می شود.
- پیکربندی نامعتبر است یا نقطه پایانی قطع ارتباط را از دست نمی دهد.
- بررسی خط مشی امنیت محتوا (CSP) انجام نمی شود.
- یک درخواست قطع ارتباط در انتظار است.
- کاربر FEDCM را در تنظیمات مرورگر غیرفعال کرده است.
هنگامی که نقطه پایانی IDP پاسخی را برمی گرداند ، RP و IDP بر روی مرورگر قطع می شوند و قول برطرف می شود. شناسه حسابهای قطع شده در پاسخ از نقطه پایانی قطع ارتباط مشخص شده است.
با FEDCM از درون یک Iframe متقاطع تماس بگیرید
اگر قاب والدین اجازه آن را بدهد ، می توان با استفاده از یک خط مشی identity-credentials-get
، از طریق یک Iframe متقاطع استفاده کرد. برای انجام این کار ، ویژگی 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")
شما می توانید در مورد نحوه عملکرد خط مشی مجوزها در کنترل ویژگی های مرورگر با خط مشی مجوز ، اطلاعات بیشتری کسب کنید.
،بیاموزید که چگونه از FEDCM برای فدراسیون هویت حفظ حریم خصوصی استفاده کنید.
FEDCM (مدیریت اعتبار فدرال) یک رویکرد حفظ حریم خصوصی برای خدمات هویت فدرال (مانند "ورود به سیستم با ...") است که کاربران می توانند بدون به اشتراک گذاشتن اطلاعات شخصی خود با سرویس هویت یا سایت ، وارد سایت ها شوند.
برای کسب اطلاعات بیشتر در مورد موارد استفاده FEDCM ، جریان کاربر و نقشه راه API مقدمه API FEDCM را بررسی کنید.
محیط توسعه FEDCM
برای استفاده از FEDCM ، به یک زمینه امن (HTTPS یا LocalHost) در IDP و RP در Chrome نیاز دارید.
کد اشکال زدایی در Chrome در Android
سرور را به صورت محلی تنظیم و اجرا کنید تا کد FEDCM خود را اشکال زد. می توانید با استفاده از کابل USB با حمل و نقل پورت ، به این سرور در Chrome در یک دستگاه Android متصل شوید .
با پیروی از دستورالعمل های موجود در دستگاه های Android از راه دور اشکال زدایی ، می توانید از DevTools on Desktop برای اشکال زدایی Chrome در Android استفاده کنید.
کوکی های شخص ثالث را روی Chrome مسدود کنید
شما می توانید قبل از اجرای آن ، چگونه FEDCM را بدون کوکی های شخص ثالث روی Chrome کار می کند.
برای مسدود کردن کوکی های شخص ثالث ، از حالت ناشناس استفاده کنید ، یا "بلوک کوکی های شخص ثالث" را در تنظیمات دسک تاپ خود در chrome://settings/cookies
یا از طریق تلفن همراه با حرکت به تنظیمات > تنظیمات سایت > کوکی ها انتخاب کنید.
از API FEDCM استفاده کنید
شما با ایجاد یک پرونده مشهور ، پرونده پیکربندی و نقاط پایانی برای لیست حساب ها ، صدور ادعا و ابرداده مشتری به صورت اختیاری با FEDCM ادغام می شوید.
از آنجا ، FEDCM API های JavaScript را که RPS می تواند برای ورود به سیستم با IDP استفاده کند ، افشا می کند.
یک فایل شناخته شده ایجاد کنید
برای جلوگیری از سوء استفاده از ردیاب API ، یک پرونده مشهور باید از /.well-known/web-identity
از ETLD+1 IDP ارائه شود.
به عنوان مثال ، اگر نقاط پایانی IDP تحت https://accounts.idp.example/
سرو می شود ، آنها باید یک فایل شناخته شده را در https://idp.example/.well-known/web-identity
و همچنین یک پرونده ارائه دهند. پرونده پیکربندی IDP . در اینجا مثالی وجود دارد که محتوای شناخته شده فایل:
{
"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
واکشی می کند. این درخواست کوکی ندارد و از تغییر مسیر پیروی نمی کند. این به طور موثری مانع از یادگیری IDP چه کسی درخواست و RP در تلاش برای اتصال است. به عنوان مثال:
GET /config.json HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity
مرورگر انتظار پاسخ JSON از IDP را دارد که شامل خواص زیر است:
اموال | توضیحات |
---|---|
accounts_endpoint (مورد نیاز) | URL برای نقطه پایانی حساب ها . |
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
را با کوکی ها با 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
پس از دریافت درخواست ، سرور باید:
- تأیید کنید که این درخواست حاوی یک
Sec-Fetch-Dest: webidentity
. - کوکی های جلسه را با شناسه حساب های ثبت شده در حال حاضر مطابقت دهید.
- با لیست حساب ها پاسخ دهید.
مرورگر انتظار پاسخ JSON را دارد که شامل یک ویژگی accounts
با مجموعه ای از اطلاعات حساب با خصوصیات زیر است:
اموال | توضیحات |
---|---|
id (لازم) | شناسه منحصر به فرد کاربر. |
name (لازم) | داده شده و نام خانوادگی کاربر. |
email (لازم) | آدرس ایمیل کاربر. |
given_name (اختیاری) | با توجه به نام کاربر. |
picture (اختیاری) | URL تصویر نماد کاربر. |
approved_clients (اختیاری) | مجموعه ای از شناسه های مشتری RP که کاربر در آن ثبت کرده است. |
login_hints (اختیاری) | مجموعه ای از انواع فیلتر ممکن که IDP برای مشخص کردن یک حساب کاربری پشتیبانی می کند. RP می تواند navigator.credentials.get() با ویژگی loginHint فراخوانی کند تا به طور انتخابی حساب مشخص شده را نشان دهد. |
domain_hints (اختیاری) | مجموعه ای از تمام دامنه هایی که حساب با آن همراه است. RP می تواند با یک ویژگی domainHint برای فیلتر کردن حساب ها با navigator.credentials.get() تماس بگیرد. |
مثال پاسخ بدن:
{
"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 و شرایط خدمات را برمی گرداند. RPS باید از قبل پیوندهایی به خط مشی رازداری و شرایط خدمات خود به IDP ارائه دهد. این پیوندها وقتی کاربر هنوز در RP با IDP ثبت نام نکرده است ، در گفتگوی ورود به سیستم نمایش داده می شود.
مرورگر با استفاده از client_id
navigator.credentials.get
بدون کوکی درخواست GET
می کند. به عنوان مثال:
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 (اختیاری) | شرایط RP URL خدمات. |
مرورگر انتظار پاسخ JSON از نقطه پایانی را دارد:
{
"privacy_policy_url": "https://rp.example/privacy_policy.html",
"terms_of_service_url": "https://rp.example/terms_of_service.html",
}
ابرداده مشتری برگشتی توسط مرورگر مصرف می شود و در دسترس RP نخواهد بود.
نقطه پایانی ادعای
نقطه پایانی ادعای شناسه IDP ادعایی را برای کاربر امضا شده خود بازگرداند. هنگامی که کاربر با استفاده از تماس با navigator.credentials.get()
به وب سایت RP وارد می شود ، مرورگر درخواست POST
را با کوکی ها با SameSite=None
و یک نوع محتوا از application/x-www-form-urlencoded
به این نقطه پایانی ارسال می کند. اطلاعات زیر:
اموال | توضیحات |
---|---|
client_id (لازم) | شناسه مشتری RP. |
account_id (لازم) | شناسه منحصر به فرد از امضا در کاربر. |
nonce (اختیاری) | درخواست Nonce ، ارائه شده توسط RP. |
disclosure_text_shown | منجر به رشته ای از "true" یا "false" (به جای یک بولی) می شود. اگر متن افشای نشان داده نشده باشد ، نتیجه "false" است. این اتفاق می افتد هنگامی که شناسه مشتری RP در لیست دارایی های approved_clients پاسخ از نقطه پایانی حساب ها قرار گرفته است یا اینکه مرورگر در صورت عدم وجود approved_clients یک لحظه ثبت نام را مشاهده کرده است. |
is_auto_selected | اگر تأیید خودکار بر روی RP انجام شود ، is_auto_selected "true" را نشان می دهد. در غیر این صورت "false" . این برای پشتیبانی از ویژگی های بیشتر مربوط به امنیت مفید است. به عنوان مثال ، برخی از کاربران ممکن است یک ردیف امنیتی بالاتر را ترجیح دهند که به واسطه صریح کاربر در تأیید اعتبار نیاز داشته باشد. اگر یک IDP بدون چنین واسطه ای درخواست توکن را دریافت کند ، می تواند درخواست را متفاوت انجام دهد. به عنوان مثال ، یک کد خطا را به گونه ای برگردانید که RP بتواند دوباره با API FEDCM با 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 پاسخ دهید (به اشتراک گذاری منابع متقاطع) .
- تأیید کنید که این درخواست حاوی یک
Sec-Fetch-Dest: webidentity
. - هدر
Origin
را در مقابل مبدا RP تعیین کنید که توسطclient_id
تعیین شده است. اگر آنها مطابقت نداشته باشند ، رد کنید. -
account_id
در برابر شناسه حساب از قبل امضا شده مطابقت دهید. اگر آنها مطابقت نداشته باشند ، رد کنید. - با یک نشانه پاسخ دهید. اگر درخواست رد شد ، با پاسخ خطا پاسخ دهید.
نحوه صدور توکن به IDP بستگی دارد ، اما به طور کلی ، با اطلاعاتی از قبیل شناسه حساب ، شناسه مشتری ، منشأ صادرکننده ، nonce
امضا می شود تا RP بتواند تأیید کند که توکن واقعی است.
مرورگر انتظار پاسخ JSON را دارد که شامل ویژگی زیر است:
اموال | توضیحات |
---|---|
token (لازم) | توکن رشته ای است که حاوی ادعاهای مربوط به احراز هویت است. |
{
"token": "***********"
}
نشانه برگشتی توسط مرورگر به RP منتقل می شود تا RP بتواند تأیید اعتبار را تأیید کند.
پاسخ خطا را برگردانید
id_assertion_endpoint
همچنین می تواند یک پاسخ "خطا" را برگرداند ، که دارای دو قسمت اختیاری است:
-
code
: IDP می تواند یکی از خطاهای شناخته شده را از لیست خطای مشخص شده OAUTH 2.0 انتخاب کند (invalid_request
،unauthorized_client
،access_denied
،server_error
وtemporarily_unavailable
) یا از هر رشته دلخواه استفاده کنید. اگر دومی ، Chrome با یک پیام خطای عمومی UI خطا را ارائه می دهد و کد را به RP منتقل می کند. -
url
: این یک صفحه وب قابل خواندن با انسانی را با اطلاعات مربوط به خطا برای ارائه اطلاعات بیشتر در مورد خطا برای کاربران مشخص می کند. این زمینه برای کاربران مفید است زیرا مرورگرها نمی توانند پیام های خطای غنی را در یک UI داخلی ارائه دهند. به عنوان مثال: پیوندها برای مراحل بعدی یا اطلاعات تماس با خدمات مشتری. اگر کاربر بخواهد در مورد جزئیات خطا و نحوه رفع آن اطلاعات بیشتری کسب کند ، می تواند برای اطلاعات بیشتر به صفحه ارائه شده از UI مرورگر مراجعه کند. URL باید از همان سایت باconfigURL
IDP باشد.
// id_assertion_endpoint response
{
"error" : {
"code": "access_denied",
"url" : "https://idp.example/error?type=access_denied"
}
}
نقطه پایانی را قطع کنید
مرورگر با استناد به IdentityCredential.disconnect()
، یک درخواست POST
متقاطع را با کوکی ها با 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 پاسخ دهید (به اشتراک گذاری منابع متقاطع) .
- تأیید کنید که این درخواست حاوی یک
Sec-Fetch-Dest: webidentity
. - هدر
Origin
را در مقابل مبدا RP تعیین کنید که توسطclient_id
تعیین شده است. اگر آنها مطابقت نداشته باشند ، رد کنید. -
account_hint
با IDS حساب های ثبت شده در حال حاضر. - حساب کاربری را از RP جدا کنید.
- با اطلاعات حساب کاربری شناسایی شده با فرمت JSON به مرورگر پاسخ دهید.
یک پاسخ به عنوان مثال JSON Payload به این شکل است:
{
"account_id": "account456"
}
در عوض ، اگر IDP آرزو می کند که مرورگر تمام حساب های مرتبط با RP را جدا کند ، رشته ای را منتقل کنید که با هیچ شناسه حساب مطابقت ندارد ، به عنوان مثال "*"
.
URL ورود
با استفاده از API وضعیت ورود به سیستم ، IDP باید وضعیت ورود کاربر را به مرورگر اطلاع دهد. با این حال ، وضعیت می تواند از همگام سازی خارج شود ، مانند زمان منقضی شدن جلسه . در چنین سناریویی ، مرورگر می تواند به صورت پویا به کاربر اجازه دهد از طریق URL صفحه ورود به سیستم ورود به سیستم IDP Config File login_url
وارد IDP شود.
گفتگوی FEDCM پیامی را نشان می دهد که یک علامت را نشان می دهد ، همانطور که در تصویر زیر نشان داده شده است.
هنگامی که کاربر روی دکمه ادامه کلیک می کند ، مرورگر یک پنجره بازشو را برای صفحه ورود به سیستم IDP باز می کند.
این گفتگو یک پنجره مرورگر معمولی است که کوکی های شخص اول دارد. هر اتفاقی که در گفتگو رخ می دهد به IDP بستگی دارد و هیچ دسته پنجره ای برای ایجاد یک درخواست ارتباطی متقاطع به صفحه RP در دسترس نیست. پس از ورود کاربر ، IDP باید:
- برای اطلاع از مرورگر که کاربر وارد سیستم شده است ،
Set-Login: logged-in
یا باnavigator.login.setStatus("logged-in")
تماس بگیرید. - برای بستن گفتگو با
IdentityProvider.close()
تماس بگیرید.
مرورگر را در مورد وضعیت ورود کاربر در ارائه دهنده هویت به مرورگر اطلاع دهید
API وضعیت ورود به سیستم مکانیسمی است که یک وب سایت ، به ویژه یک IDP ، وضعیت ورود کاربر را در IDP به مرورگر اطلاع می دهد. با استفاده از این API ، مرورگر می تواند درخواست های غیر ضروری را به IDP کاهش داده و حملات زمان بندی بالقوه را کاهش دهد.
IDP ها می توانند با ارسال یک هدر HTTP یا با تماس با API JavaScript هنگام ورود کاربر در IDP یا هنگام ورود کاربر از تمام حساب های IDP ، وضعیت ورود کاربر را به مرورگر نشان دهند. برای هر IDP (که توسط URL پیکربندی آن مشخص شده است) مرورگر یک متغیر سه حالت را نشان می دهد که وضعیت ورود به سیستم را با مقادیر احتمالی logged-in
، logged-out
و unknown
نشان می دهد. حالت پیش فرض unknown
است.
برای اینکه سیگنال شود که کاربر وارد سیستم شده است ، یک 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 Calling FedCM درخواست هایی را به نقطه پایانی حساب های IDP می دهد و حساب های موجود را در گفتگوی FEDCM به کاربر نشان می دهد.
برای نشان دادن اینکه کاربر از تمام حسابهای خود امضا شده است ، 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
برای انتقال بهتر معرفی شد ، زیرا ممکن است کاربر هنگام حمل این API وارد IDP شود. IDP ممکن است فرصتی برای سیگنال این موضوع به مرورگر نداشته باشد تا زمانی که برای اولین بار FEDCM فراخوانی شود. در این حالت ، Chrome درخواستی را به نقطه پایانی حساب های IDP ارائه می دهد و وضعیت را بر اساس پاسخ از نقطه پایانی حساب ها به روز می کند:
- اگر نقطه پایانی لیستی از حسابهای فعال را بازگرداند ، وضعیت را برای
logged-in
به روز کنید و گفتگوی FEDCM را باز کنید تا آن حساب ها را نشان دهید. - اگر نقطه پایانی هیچ حساب را برنگردد ، وضعیت را برای
logged-out
به روز کنید و تماس FEDCM را شکست دهید.
بگذارید کاربر از طریق یک جریان ورود به سیستم پویا وارد سیستم شود
حتی اگر IDP وضعیت ورود به سیستم کاربر را به مرورگر اطلاع می دهد ، می تواند از همگام سازی خارج شود ، مانند زمان منقضی شدن جلسه. مرورگر سعی می کند هنگام logged-in
یک درخواست معتبر را به نقطه پایانی حساب ارسال کند ، اما سرور هیچ حساب نمی کند زیرا جلسه دیگر در دسترس نیست. در چنین سناریویی ، مرورگر می تواند به صورت پویا اجازه دهد کاربر از طریق پنجره بازشو وارد IDP شود .
با ارائه دهنده هویت وارد حزب متکی شوید
پس از در دسترس بودن پیکربندی و نقاط پایانی IDP ، RP ها می توانند با navigator.credentials.get()
تماس بگیرند تا به کاربران اجازه دهد تا با IDP وارد RP شوند.
قبل از تماس با 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
در پاسخ از نقطه پایانی لیست حساب ، موارد ثبت نام و استفاده از ورود به سیستم را متفاوت می کند. اگر کاربر قبلاً در RP ثبت نام کرده است ، مرورگر متن افشای "برای ادامه با ...." را نشان نمی دهد.
وضعیت ثبت نام بر اساس این که آیا شرایط زیر برآورده شده است یا خیر ، تعیین می شود:
- در صورت
approved_clients
شاملclientId
RP است. - اگر مرورگر به یاد داشته باشد که کاربر قبلاً در RP ثبت نام کرده است.
هنگامی که RP تماس می گیرد navigator.credentials.get()
، فعالیت های زیر انجام می شود:
- مرورگر درخواست ها را ارسال می کند و چندین سند را واکشی می کند:
- پرونده مشهور و یک پرونده پیکربندی IDP که نقاط پایانی را اعلام می کنند.
- یک لیست حساب
- اختیاری: URL هایی برای خط مشی رازداری RP و شرایط خدمات ، که از نقطه پایانی ابرداده مشتری گرفته شده است.
- مرورگر لیست حساب هایی را که کاربر می تواند برای ورود به سیستم استفاده کند ، و همچنین شرایط خدمات و خط مشی رازداری در صورت وجود نشان می دهد.
- هنگامی که کاربر یک حساب کاربری را برای ورود به سیستم انتخاب کرد ، درخواستی به نقطه پایانی ادعای شناسه برای بازیابی یک نشانه به IDP ارسال می شود.
- RP می تواند نشانه را برای تأیید اعتبار کاربر تأیید کند.
انتظار می رود RP ها از مرورگرهایی که از FEDCM پشتیبانی نمی کنند ، پشتیبانی کند ، بنابراین کاربران باید بتوانند از یک فرآیند ورود به سیستم موجود و غیر FEDCM استفاده کنند. تا زمانی که کوکی های شخص ثالث دیگر در مرورگرها در دسترس نباشند ، این مسئله باید بدون مشکل باقی بماند.
پس از تأیید توکن توسط سرور RP ، RP ممکن است کاربر را ثبت کند یا به آنها اجازه ورود داده و یک جلسه جدید را شروع کند.
ورود به سیستم API
پس از ورود کاربر ، گاهی اوقات طرف متکی (RP) از کاربر می خواهد که مجدداً تأیید شود. اما ممکن است کاربر مطمئن نباشد از کدام حساب کاربری استفاده کرده است. اگر RP بتواند با کدام حساب کاربری وارد شود ، انتخاب حساب کاربری برای کاربر ساده تر خواهد بود.
RPS می تواند با فراخوانی 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 ورود به سیستم مشخص شده در پرونده پیکربندی باز می شود. پیوند سپس با پارامترهای Login Hint و Domain Hint Query ضمیمه می شود.
API Domain Hint
مواردی وجود دارد که RP از قبل می داند که فقط حسابهای مرتبط با یک دامنه خاص مجاز به ورود به سایت هستند. این امر به ویژه در سناریوهای سازمانی که در آن به سایت دسترسی پیدا می کند محدود به یک دامنه شرکت است. برای ارائه یک تجربه کاربری بهتر ، API FEDCM به RP اجازه می دهد تا فقط حسابهایی را که ممکن است برای ورود به RP استفاده شود ، نشان دهد. این مانع از سناریوهایی می شود که کاربر سعی می کند با استفاده از یک حساب کاربری در خارج از دامنه شرکت به RP وارد شود ، فقط با یک پیام خطا بعداً (یا سکوت جایی که ورود به سیستم کار نمی کند) ارائه می شود زیرا از نوع مناسب حساب استفاده نشده است.
RPS می تواند با استفاده از 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 ورود به سیستم مشخص شده در پرونده پیکربندی باز می شود. پیوند سپس با پارامترهای Login Hint و Domain Hint Query ضمیمه می شود.
پیام خطا را نشان دهید
بعضی اوقات ، IDP ممکن است به دلایل قانونی نتواند نشانه ای صادر کند ، مانند زمانی که مشتری غیرمجاز است ، سرور به طور موقت در دسترس نیست. اگر IDP پاسخ "خطا" را برگرداند ، RP می تواند آن را بدست آورد ، و همچنین Chrome با نشان دادن UI مرورگر با اطلاعات خطایی که توسط 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;
}
پس از احراز هویت اولیه ، کاربران معتبر خودکار
Auto-Authententication FedCM (به طور خلاصه "Auto-Reeauthn") می تواند به کاربران اجازه دهد که پس از احراز هویت اولیه خود با استفاده از FEDCM ، به طور خودکار مجدداً تأیید کنند. "احراز هویت اولیه" در اینجا به این معنی است که کاربر با ضربه زدن روی دکمه "ادامه به عنوان ..." در گفتگوی ورود به سیستم 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
یک خاصیت در API مدیریت اعتبار است ، به همان روشی که برای گذرواژنی و فدرال فدرال انجام می شود رفتار می کند و بخشی از آن توسط PublicKeyCredential نیز پشتیبانی می شود. این ملک چهار مقدار زیر را می پذیرد:
-
'optional'
(پیش فرض): در صورت امکان خودکار ، در صورت عدم نیاز به واسطه ای نیاز دارد. توصیه می کنیم این گزینه را در صفحه ورود به سیستم انتخاب کنید. -
'required'
: همیشه برای ادامه کار با کلیک بر روی دکمه "ادامه" روی UI ، به واسطه ای نیاز دارد. اگر انتظار می رود کاربران شما هر بار که نیاز به تأیید اعتبار داشته باشند ، این گزینه را انتخاب کنید. -
'silent'
: در صورت امکان خودکار ، بی سکوت بدون نیاز به واسطه گری در صورت عدم موفقیت. ما توصیه می کنیم این گزینه را در صفحات غیر از صفحه ورود به سیستم اختصاصی انتخاب کنید اما در جایی که می خواهید کاربران را وارد سیستم کنید-برای مثال ، یک صفحه مورد در یک وب سایت حمل و نقل یا یک صفحه مقاله در یک وب سایت خبری. -
'conditional'
: برای WebAuthn استفاده می شود و در حال حاضر برای FEDCM در دسترس نیست.
با این تماس ، Auto-reeauthn تحت شرایط زیر اتفاق می افتد:
- FEDCM برای استفاده در دسترس است. به عنوان مثال ، کاربر FEDCM را در سطح جهان یا RP در تنظیمات غیرفعال نکرده است.
- کاربر فقط از یک حساب با FEDCM API برای ورود به وب سایت در این مرورگر استفاده کرد.
- کاربر با آن حساب وارد IDP می شود.
- ریل خودکار در 10 دقیقه گذشته اتفاق نیفتاد.
- RP پس از ورود به سیستم قبلی ،
navigator.credentials.preventSilentAccess()
را فراخوانی نکرده است.
هنگامی که این شرایط برآورده می شود ، تلاش برای تأیید خودکار کاربر به محض فراخوانی FEDCM navigator.credentials.get()
شروع می شود.
در هنگام mediation: optional
، به دلیل دلایلی که فقط مرورگر می داند ممکن است در دسترس نباشد . RP می تواند بررسی کند که آیا با بررسی خاصیت isAutoSelected
، آیا Reauthn خودکار انجام می شود یا خیر.
این برای ارزیابی عملکرد API و بهبود UX بر این اساس مفید است. Also, when it's unavailable, the user may be prompted to sign in with explicit user mediation, which is a flow with mediation: required
.
Enforce mediation with preventSilentAccess()
Auto-reauthenticating users immediately after they sign out wouldn't make for a very good user experience. That's why FedCM has a 10-minute quiet period after an auto-reauthn to prevent this behavior. This means that auto-reauthn happens at most once in every 10-minutes unless the user signs back in within 10-minutes. The RP should call navigator.credentials.preventSilentAccess()
to explicitly request the browser to disable auto-reauthn when a user signs out of the RP explicitly, for example, by clicking a sign-out button.
function signout() {
navigator.credentials.preventSilentAccess();
location.href = '/signout';
}
Users can opt-out of auto-reauthn in settings
Users can opt-out from auto-reauth from the settings menu:
- On desktop Chrome, go to
chrome://password-manager/settings
> Sign in automatically. - On Android Chrome, open Settings > Password Manager > Tap on a cog at the top right corner > Auto sign-in.
By disabling the toggle, the user can opt-out from auto-reauthn behavior all together. This setting is stored and synchronized across devices, if the user is signed into a Google Account on the Chrome instance and synchronization is enabled.
Disconnect the IdP from the RP
If a user has previously signed into the RP using the IdP through FedCM, the relationship is memorized by the browser locally as the list of connected accounts. The RP may initiate a disconnection by invoking the IdentityCredential.disconnect()
function. This function can be called from a top-level RP frame. The RP needs to pass a configURL
, the clientId
it uses under the IdP, and an accountHint
for the IdP to be disconnected. An account hint can be an arbitrary string as long as the disconnect endpoint can identify the account, for example an email address or user ID which does not necessarily match the account ID that the account list endpoint has provided:
// 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()
returns a Promise
. This promise may throw an exception for the following reasons:
- The user hasn't signed in to the RP using the IdP through FedCM.
- The API is invoked from within an iframe without FedCM permissions policy.
- The configURL is invalid or missing the disconnect endpoint.
- Content Security Policy (CSP) check fails.
- There is a pending disconnect request.
- The user has disabled FedCM in the browser settings.
When the IdP's disconnect endpoint returns a response , the RP and the IdP are disconnected on the browser and the promise is resolved. The ID of the disconnected accounts are specified in the response from the disconnect endpoint .
Call FedCM from within a cross-origin iframe
FedCM can be invoked from within a cross-origin iframe using an identity-credentials-get
permissions policy, if the parent frame allows it. To do so, append the allow="identity-credentials-get"
attribute to the iframe tag as follows:
<iframe src="https://fedcm-cross-origin-iframe.glitch.me" allow="identity-credentials-get"></iframe>
You can see it in action in an example .
Optionally, if the parent frame wants to restrict the origins to call FedCM, send a Permissions-Policy
header with a list of allowed origins.
Permissions-Policy: identity-credentials-get=(self "https://fedcm-cross-origin-iframe.glitch.me")
You can learn more about how the Permissions Policy works at Controlling browser features with Permissions Policy .
،Learn how to use FedCM for privacy-preserving identity federation.
FedCM (Federated Credential Management) is a privacy-preserving approach to federated identity services (such as "Sign in with...") where users can log into sites without sharing their personal information with the identity service or the site.
To learn more about FedCM use cases, user flows, and API roadmap check out the introduction to FedCM API .
FedCM development environment
You need a secure context (HTTPS or localhost) both on the IdP and RP in Chrome to use the FedCM.
Debug code on Chrome on Android
Set up and run a server locally to debug your FedCM code. You can access this server in Chrome on an Android device connected using a USB cable with port forwarding.
You can use DevTools on desktop to debug Chrome on Android by following the instructions at Remote debug Android devices .
Block third-party cookies on Chrome
You can test how FedCM works without third-party cookies on Chrome before it's actually enforced.
To block third-party cookies, use Incognito mode , or choose "Block third-party cookies" in your desktop settings at chrome://settings/cookies
or on mobile by navigating to Settings > Site settings > Cookies .
Use the FedCM API
You integrate with FedCM by creating a well-known file , config file and endpoints for accounts list , assertion issuance and optionally client metadata .
From there, FedCM exposes JavaScript APIs that RPs can use to sign in with the IdP.
Create a well-known file
To prevent trackers from abusing the API , a well-known file must be served from /.well-known/web-identity
of eTLD+1 of the IdP.
For example, if the IdP endpoints are served under https://accounts.idp.example/
, they must serve a well-known file at https://idp.example/.well-known/web-identity
as well as an IdP config file . Here's an example well-known file content:
{
"provider_urls": ["https://accounts.idp.example/config.json"]
}
The JSON file must contain the provider_urls
property with an array of IdP config file URLs that can be specified as a path part of configURL
in navigator.credentials.get
by RPs . The number of URL strings in the array is limited to one, but this may change with your feedback in the future.
Create an IdP config file and endpoints
The IdP config file provides a list of required endpoints for the browser. IdPs will host this config file and the required endpoints and URLs. All JSON responses must be served with application/json
content-type.
The config file's URL is determined by the values provided to the navigator.credentials.get
call executed on an RP .
const credential = await navigator.credentials.get({
identity: {
context: 'signup',
providers: [{
configURL: 'https://accounts.idp.example/config.json',
clientId: '********',
nonce: '******'
}]
}
});
const { token } = credential;
Specify a full URL of the IdP config file location as a configURL
. When navigator.credentials.get()
is called on the RP, the browser fetches the config file with a GET
request without the Origin
header or the Referer
header. The request doesn't have cookies and doesn't follow redirects. This effectively prevents the IdP from learning who made the request and which RP is attempting to connect. به عنوان مثال:
GET /config.json HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity
The browser expects a JSON response from the IdP which includes the following properties:
اموال | توضیحات |
---|---|
accounts_endpoint (required) | URL for the accounts endpoint . |
client_metadata_endpoint (optional) | URL for the client metadata endpoint . |
id_assertion_endpoint (required) | URL for the ID assertion endpoint . |
disconnect (optional) | URL for the disconnect endpoint . |
login_url (required) | The login page URL for the user to sign in to the IdP. |
branding (optional) | Object which contains various branding options. |
branding.background_color (optional) | Branding option which sets the background color of the "Continue as..." button. Use the relevant CSS syntax, namely hex-color , hsl() , rgb() , or named-color . |
branding.color (optional) | Branding option which sets the text color of the "Continue as..." button. Use the relevant CSS syntax, namely hex-color , hsl() , rgb() , or named-color . |
branding.icons (optional) | Branding option which sets the icon object, displayed in the sign-in dialog. The icon object is an array with two parameters:
|
RP could modify the string in the FedCM dialog UI using the identity.context
value for navigator.credentials.get()
to accommodate predefined authentication contexts. Optional property can be one of "signin"
(default), "signup"
, "use"
or "continue"
.
Here's an example response body from the 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
}]
}
}
Once the browser fetches the config file, it sends subsequent requests to the IdP endpoints:
Accounts endpoint
The IdP's accounts endpoint returns a list of accounts that the user is signed in on the IdP. If the IdP supports multiple accounts, this endpoint will return all signed in accounts.
The browser sends a GET
request with cookies with SameSite=None
, but without a client_id
parameter, the Origin
header or the Referer
header. This effectively prevents the IdP from learning which RP the user is trying to sign in to. به عنوان مثال:
GET /accounts.php HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
Upon receiving the request, the server should:
- Verify that the request contains a
Sec-Fetch-Dest: webidentity
HTTP header. - Match the session cookies with the IDs of the already signed-in accounts.
- Respond with the list of accounts.
The browser expects a JSON response that includes an accounts
property with an array of account information with following properties:
اموال | توضیحات |
---|---|
id (required) | Unique ID of the user. |
name (required) | Given and family name of the user. |
email (required) | Email address of the user. |
given_name (optional) | Given name of the user. |
picture (optional) | URL of the user avatar image. |
approved_clients (optional) | An array of RP client IDs which the user has registered with. |
login_hints (optional) | An array of all possible filter types that the IdP supports to specify an account. The RP can invoke navigator.credentials.get() with the loginHint property to selectively show the specified account. |
domain_hints (optional) | An array of all the domains the account is associated with. The RP can call navigator.credentials.get() with a domainHint property to filter the accounts. |
Example response body:
{
"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"]
}]
}
If the user is not signed in, respond with HTTP 401 (Unauthorized).
The returned accounts list is consumed by the browser and won't be available to the RP.
Client metadata endpoint
The IdP's client metadata endpoint returns the relying party's metadata such as the RP's privacy policy and terms of service. RPs should provide links to their privacy policy and terms of service to the IdP in advance. These links are displayed in the sign-in dialog when the user hasn't registered on the RP with the IdP yet.
The browser sends a GET
request using the client_id
navigator.credentials.get
without cookies. به عنوان مثال:
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
Upon receiving the request, the server should:
- Determine the RP for the
client_id
. - Respond with the client metadata.
The properties for the client metadata endpoint include:
اموال | توضیحات |
---|---|
privacy_policy_url (optional) | RP privacy policy URL. |
terms_of_service_url (optional) | RP terms of service URL. |
The browser expects a JSON response from the endpoint:
{
"privacy_policy_url": "https://rp.example/privacy_policy.html",
"terms_of_service_url": "https://rp.example/terms_of_service.html",
}
The returned client metadata is consumed by the browser and won't be available to the RP.
ID assertion endpoint
The IdP's ID assertion endpoint returns an assertion for their signed-in user. When the user signs in to an RP website using navigator.credentials.get()
call , the browser sends a POST
request with cookies with SameSite=None
and a content-type of application/x-www-form-urlencoded
to this endpoint with اطلاعات زیر:
اموال | توضیحات |
---|---|
client_id (required) | The RP's client identifier. |
account_id (required) | The unique ID of the signing in user. |
nonce (optional) | The request nonce, provided by the RP. |
disclosure_text_shown | Results in a string of "true" or "false" (rather than a boolean). The result is "false" if the disclosure text was not shown. This happens when the RP's client ID was included in the approved_clients property list of the response from the accounts endpoint or if the browser has observed a sign-up moment in the past in the absence of approved_clients . |
is_auto_selected | If auto-reauthentication is performed on the RP, is_auto_selected indicates "true" . Otherwise "false" . This is helpful to support more security related features. For example, some users may prefer a higher security tier which requires explicit user mediation in authentication. If an IdP receives a token request without such mediation, they could handle the request differently. For example, return an error code such that the RP can call the FedCM API again with mediation: required . |
Example HTTP header:
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
Upon receiving the request, the server should:
- Respond to the request with CORS (Cross-Origin Resource Sharing) .
- Verify that the request contains a
Sec-Fetch-Dest: webidentity
HTTP header. - Match the
Origin
header against the RP origin determine by theclient_id
. Reject if they don't match. - Match
account_id
against the ID of the already signed-in account. Reject if they don't match. - Respond with a token. If the request is rejected, respond with an error response .
How the token is issued is up to the IdP, but in general, it's signed with information such as the account ID, client ID, issuer origin, nonce
, so that the RP can verify the token is genuine.
The browser expects a JSON response that includes the following property:
اموال | توضیحات |
---|---|
token (required) | A token is a string that contains claims about the authentication. |
{
"token": "***********"
}
The returned token is passed to the RP by the browser, so that the RP can validate the authentication.
Return an error response
The id_assertion_endpoint
can also return an "error" response, which has two optional fields:
-
code
: The IdP can choose one of the known errors from the OAuth 2.0 specified error list (invalid_request
,unauthorized_client
,access_denied
,server_error
andtemporarily_unavailable
) or use any arbitrary string. If the latter, Chrome renders the error UI with a generic error message and pass the code to the RP. -
url
: It identifies a human-readable web page with information about the error to provide additional information about the error to users. This field is useful to users because browsers cannot provide rich error messages in a built-in UI. For example: links for next steps, or customer service contact information. If a user wants to learn more about the error details and how to fix it, they could visit the provided page from the browser UI for more details. The URL must be of the same-site as the IdPconfigURL
.
// id_assertion_endpoint response
{
"error" : {
"code": "access_denied",
"url" : "https://idp.example/error?type=access_denied"
}
}
Disconnect endpoint
By invoking IdentityCredential.disconnect()
, the browser sends a cross-origin POST
request with cookies with SameSite=None
and a content-type of application/x-www-form-urlencoded
to this disconnect endpoint with the following information:
اموال | توضیحات |
---|---|
account_hint | A hint for the IdP account.. |
client_id | The RP's client identifier. |
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
Upon receiving the request, the server should:
- Respond to the request with CORS (Cross-Origin Resource Sharing) .
- Verify that the request contains a
Sec-Fetch-Dest: webidentity
HTTP header. - Match the
Origin
header against the RP origin determine by theclient_id
. Reject if they don't match. - Match
account_hint
against the IDs of the already signed-in accounts. - Disconnect the user account from the RP.
- Respond to the browser with the identified user account information in a JSON format.
An example response JSON payload looks like this:
{
"account_id": "account456"
}
Instead, if the IdP wishes the browser to disconnect all accounts associated with the RP, pass a string that does not match any account ID, for example "*"
.
URL ورود
With the Login Status API , the IdP must inform the user's login status to the browser. However, the status could be out of sync, such as when the session expires . In such a scenario, the browser can dynamically let the user sign in to the IdP through the login page URL specified with the idp config file 's login_url
.
The FedCM dialog displays a message suggesting a sign in, as shown in the following image.
When the user clicks the Continue button, the browser opens a popup window for the IdP's login page.
The dialog is a regular browser window that has first-party cookies. Whatever happens within the dialog is up to the IdP, and no window handles are available to make a cross-origin communication request to the RP page. After the user is signed in, the IdP should:
- Send the
Set-Login: logged-in
header or call thenavigator.login.setStatus("logged-in")
API to inform the browser that the user has been signed in. - Call
IdentityProvider.close()
to close the dialog.
Inform the browser about the user's login status on the identity provider
The Login Status API is a mechanism where a website, especially an IdP, informs the browser the user's login status on the IdP. With this API, the browser can reduce unnecessary requests to the IdP and mitigate potential timing attacks.
IdPs can signal the user's login status to the browser by sending an HTTP header or by calling a JavaScript API when the user is signed in on the IdP or when the user is signed out from all their IdP accounts. For each IdP (identified by its config URL) the browser keeps a tri-state variable representing the login state with possible values logged-in
, logged-out
, and unknown
. The default state is unknown
.
To signal that the user is signed in, send an Set-Login: logged-in
HTTP header in a top-level navigation or a same-site subresource request at the IdP origin:
Set-Login: logged-in
Alternatively, call the JavaScript API navigator.login.setStatus("logged-in")
from the IdP origin in a top-level navigation:
navigator.login.setStatus("logged-in")
These calls record the user's login status as logged-in
. When the user's login status is set to logged-in
, the RP calling FedCM makes requests to the IdP's accounts endpoint and displays available accounts to the user in the FedCM dialog.
To signal that the user is signed out from all their accounts, send Set-Login: logged-out
HTTP header in a top-level navigation or a same-site subresource request at the IdP origin:
Set-Login: logged-out
Alternatively, call the JavaScript API navigator.login.setStatus("logged-out")
from the IdP origin in a top-level navigation:
navigator.login.setStatus("logged-out")
These calls record the user's login status as logged-out
. When the user's login status is logged-out
, calling the FedCM silently fails without making a request to the IdP's accounts endpoint.
The unknown
status is set before the IdP sends a signal using the Login Status API. Unknown
was introduced for a better transition, because a user may have already signed into the IdP when this API was shipped. The IdP may not have a chance to signal this to the browser by the time FedCM is first invoked. In this case, Chrome makes a request to the IdP's accounts endpoint and update the status based on the response from the accounts endpoint:
- If the endpoint returns a list of active accounts, update the status to
logged-in
and open the FedCM dialog to show those accounts. - If the endpoint returns no accounts, update the status to
logged-out
and fail the FedCM call.
Let the user sign in through a dynamic login flow
Even though the IdP keeps informing the user's login status to the browser, it could be out of sync, such as when the session expires. The browser tries to send a credentialed request to the accounts endpoint when the login status is logged-in
, but the server returns no accounts because the session is no longer available. In such a scenario, the browser can dynamically let the user sign in to the IdP through a popup window .
Sign in to the relying party with the identity provider
Once the IdP's configuration and endpoints are available, RPs can call navigator.credentials.get()
to request allowing users to sign in to the RP with the IdP.
Before calling the API, you need to confirm that FedCM is available on the user's browser . To check if FedCM is available, wrap this code around your FedCM implementation:
if ('IdentityCredential' in window) {
// If the feature is available, take action
}
To request allowing users to sign in to the IdP from the RP, do the following, for example:
const credential = await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://accounts.idp.example/config.json',
clientId: '********',
nonce: '******'
}]
}
});
const { token } = credential;
The providers
property takes an array of IdentityProvider
objects that have the following properties:
اموال | توضیحات |
---|---|
configURL (required) | A full path of the IdP config file. |
clientId (required) | The RP's client identifier, issued by the IdP. |
nonce (optional) | A random string to ensure the response is issued for this specific request. Prevents replay attacks. |
loginHint (optional) | By specifying one of login_hints values provided by the accounts endpoints , the FedCM dialog selectively shows the specified account. |
domainHint (optional) | By specifying one of domain_hints values provided by the accounts endpoints , the FedCM dialog selectively show the specified account. |
The browser handles sign-up and sign-in use cases differently depending on the existence of approved_clients
in the response from the accounts list endpoint . The browser won't display a disclosure text "To continue with ...." if the user has already signed up to the RP.
The sign-up state is determined based on whether the following conditions are fulfilled or not:
- If
approved_clients
includes the RP'sclientId
. - If the browser remembers that the user has already signed up to the RP.
When the RP calls navigator.credentials.get()
, the following activities take place:
- The browser sends requests and fetches several documents:
- The well-known file and an IdP config file which declare endpoints.
- An accounts list .
- Optional: URLs for the RP's privacy policy and terms of service, retrieved from the client metadata endpoint .
- The browser displays the list of accounts that the user can use to sign-in, as well as the terms of service and privacy policy if available.
- Once the user chooses an account to sign in with, a request to the ID assertion endpoint is sent to the IdP to retrieve a token.
- The RP can validate the token to authenticate the user.
RPs are expected to support browsers which don't support FedCM, therefore users should be able to use an existing, non-FedCM sign-in process. Until third-party cookies are no longer available in browsers, this should remain non-problematic.
Once the token is validated by the RP server, the RP may register the user or let them sign-in and start a new session.
Login Hint API
After the user signs in, sometimes the relying party (RP) asks the user to reauthenticate. But the user may not be sure which account they've been using. If the RP can specify which account to sign in with, it would be easier for the user to pick an account.
RPs can selectively show a specific account by invoking navigator.credentials.get()
with the loginHint
property with one of login_hints
values fetched from the accounts list endpoint , as shown in the following code sample:
return await navigator.credentials.get({
identity: {
providers: [{
configURL: "https://idp.example/manifest.json",
clientId: "123",
nonce: nonce,
loginHint : "demo1@example.com"
}]
}
});
When no accounts match the loginHint
, the FedCM dialog shows a login prompt, which allows the user to login to an IdP account matching the hint requested by the RP. When the user taps on the prompt, a popup window is opened with the login URL specified in the config file . The link is then appended with the login hint and the domain hint query parameters.
Domain Hint API
There are cases where the RP already knows that only accounts associated with a certain domain are allowed to login to the site. This is particularly common in enterprise scenarios where the site being accessed is restricted to a corporate domain. To provide a better user experience, the FedCM API allows the RP to only show the accounts which may be used to login to the RP. This prevents scenarios where a user tries to login to the RP using an account outside of the corporate domain, only to be served with an error message later (or silence where the login did not work) because the right type of account was not used.
RPs can selectively show only matching accounts by invoking navigator.credentials.get()
with the domainHint
property with one of domain_hints
values fetched from the accounts list endpoint , as shown in the following code sample:
return await navigator.credentials.get({
identity: {
providers: [{
configURL: "https://idp.example/manifest.json",
clientId: "abc",
nonce: nonce,
domainHint : "corp.example"
}]
}
});
When no accounts match the domainHint
, the FedCM dialog shows a login prompt, which allows the user to login to an IdP account matching the hint requested by the RP. When the user taps on the prompt, a popup window is opened with the login URL specified in the config file . The link is then appended with the login hint and the domain hint query parameters.
Show an error message
Sometimes, the IdP may not be able to issue a token for legitimate reasons, such as when the client is unauthorized, the server is temporarily unavailable. If the IdP returns an "error" response, the RP can catch it, as well as Chrome notifies the user by showing a browser UI with the error information provided by the 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;
}
Auto-reauthenticate users after the initial authentication
FedCM auto-reauthentication ("auto-reauthn" in short) can let users reauthenticate automatically, when they come back after their initial authentication using FedCM. "The initial authentication" here means the user creates an account or signs into the RP's website by tapping on the "Continue as..." button on FedCM's sign-in dialog for the first time on the same browser instance.
While the explicit user experience makes sense before the user has created the federated account to prevent tracking (which is one of the main goals of FedCM), it is unnecessarily cumbersome after the user has gone through it once: after the user grants permission to allow communication between the RP and the IdP, there's no privacy or security benefit for enforcing another explicit user confirmation for something that they have already previously acknowledged.
With auto-reauthn, the browser changes its behavior depending on the option you specify for the mediation
when calling 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;
The mediation
is a property in the Credential Management API , it behaves in the same way as it does for PasswordCredential and FederatedCredential and it's partially supported by PublicKeyCredential as well. The property accepts the following four values:
-
'optional'
(default): Auto-reauthn if possible, requires a mediation if not. We recommend choosing this option on the sign-in page. -
'required'
: Always requires a mediation to proceed, for example, clicking the "Continue" button on the UI. Choose this option if your users are expected to grant permission explicitly every time they need to be authenticated. -
'silent'
: Auto-reauthn if possible, silently fail without requiring a mediation if not. We recommend choosing this option on the pages other than the dedicated sign-in page but where you want to keep users signed in—for example, an item page on a shipping website or an article page on a news website. -
'conditional'
: Used for WebAuthn and not available for FedCM at the moment.
With this call, auto-reauthn happens under the following conditions:
- FedCM is available to use. For example, the user has not disabled FedCM either globally or for the RP in the settings.
- The user used only one account with FedCM API to sign into the website on this browser.
- The user is signed into the IdP with that account.
- The auto-reauthn didn't happen within the last 10 minutes.
- The RP hasn't called
navigator.credentials.preventSilentAccess()
after the previous sign in.
When these conditions are met, an attempt to automatically reauthenticate the user starts as soon as the FedCM navigator.credentials.get()
is invoked.
When mediation: optional
, auto-reauthn may be unavailable due to reasons that only the browser knows; the RP can check whether auto-reauthn is performed by examining the isAutoSelected
property.
This is helpful to evaluate the API performance and improve UX accordingly. Also, when it's unavailable, the user may be prompted to sign in with explicit user mediation, which is a flow with mediation: required
.
Enforce mediation with preventSilentAccess()
Auto-reauthenticating users immediately after they sign out wouldn't make for a very good user experience. That's why FedCM has a 10-minute quiet period after an auto-reauthn to prevent this behavior. This means that auto-reauthn happens at most once in every 10-minutes unless the user signs back in within 10-minutes. The RP should call navigator.credentials.preventSilentAccess()
to explicitly request the browser to disable auto-reauthn when a user signs out of the RP explicitly, for example, by clicking a sign-out button.
function signout() {
navigator.credentials.preventSilentAccess();
location.href = '/signout';
}
Users can opt-out of auto-reauthn in settings
Users can opt-out from auto-reauth from the settings menu:
- On desktop Chrome, go to
chrome://password-manager/settings
> Sign in automatically. - On Android Chrome, open Settings > Password Manager > Tap on a cog at the top right corner > Auto sign-in.
By disabling the toggle, the user can opt-out from auto-reauthn behavior all together. This setting is stored and synchronized across devices, if the user is signed into a Google Account on the Chrome instance and synchronization is enabled.
Disconnect the IdP from the RP
If a user has previously signed into the RP using the IdP through FedCM, the relationship is memorized by the browser locally as the list of connected accounts. The RP may initiate a disconnection by invoking the IdentityCredential.disconnect()
function. This function can be called from a top-level RP frame. The RP needs to pass a configURL
, the clientId
it uses under the IdP, and an accountHint
for the IdP to be disconnected. An account hint can be an arbitrary string as long as the disconnect endpoint can identify the account, for example an email address or user ID which does not necessarily match the account ID that the account list endpoint has provided:
// 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()
returns a Promise
. This promise may throw an exception for the following reasons:
- The user hasn't signed in to the RP using the IdP through FedCM.
- The API is invoked from within an iframe without FedCM permissions policy.
- The configURL is invalid or missing the disconnect endpoint.
- Content Security Policy (CSP) check fails.
- There is a pending disconnect request.
- The user has disabled FedCM in the browser settings.
When the IdP's disconnect endpoint returns a response , the RP and the IdP are disconnected on the browser and the promise is resolved. The ID of the disconnected accounts are specified in the response from the disconnect endpoint .
Call FedCM from within a cross-origin iframe
FedCM can be invoked from within a cross-origin iframe using an identity-credentials-get
permissions policy, if the parent frame allows it. To do so, append the allow="identity-credentials-get"
attribute to the iframe tag as follows:
<iframe src="https://fedcm-cross-origin-iframe.glitch.me" allow="identity-credentials-get"></iframe>
You can see it in action in an example .
Optionally, if the parent frame wants to restrict the origins to call FedCM, send a Permissions-Policy
header with a list of allowed origins.
Permissions-Policy: identity-credentials-get=(self "https://fedcm-cross-origin-iframe.glitch.me")
You can learn more about how the Permissions Policy works at Controlling browser features with Permissions Policy .