FedCM (مدیریت اعتبار فدراسیونی) یک رویکرد حفظ حریم خصوصی برای خدمات هویتی فدرال (مانند "ورود به سیستم با...") است که به کاربران اجازه می دهد بدون به اشتراک گذاشتن اطلاعات شخصی خود با سرویس هویت یا سایت وارد سایت ها شوند.
پیاده سازی FedCM شامل چندین مرحله اصلی برای IdP (ارائه دهنده هویت) و RP (حزب متکی) است.
IdP ها برای پیاده سازی FedCM باید مراحل زیر را انجام دهند:
- یک فایل شناخته شده ایجاد کنید.
- یک فایل کانفیگ ایجاد کنید.
- نقاط پایانی زیر را ایجاد کنید:
- مرورگر را از وضعیت ورود کاربر مطلع کنید.
RP ها باید مراحل زیر را برای فعال کردن FedCM در سایت خود انجام دهند:
- مطمئن شوید که نقاط پایانی FedCM در سایت RP مجاز است .
- از FedCM JavaScript API برای شروع احراز هویت کاربر استفاده کنید.
- ابردادههای آنها (مانند آدرسهای اینترنتی خطمشی رازداری و شرایط خدمات) را در اختیار IdP قرار دهید
- [اختیاری] با انتخاب حالت UX ، ارائه نکات ورود به سیستم یا دامنه ، ارسال پارامترهای سفارشی ، درخواست اطلاعات کاربر خاص ، ارائه یک پیام خطای سفارشی ، یا انتخاب نحوه احراز هویت مجدد کاربران، تجربه کاربر را سفارشی کنید.
FedCM را به عنوان یک IdP پیاده سازی کنید
درباره مراحل اجرای FedCM در سمت IdP بیشتر بدانید.
یک فایل شناخته شده ایجاد کنید
برای جلوگیری از سوء استفاده ردیابها از API ، یک فایل شناخته شده باید از /.well-known/web-identity
eTLD+1 IdP ارائه شود.
فایل شناخته شده می تواند شامل ویژگی های زیر باشد:
اموال | مورد نیاز | توضیحات |
---|---|---|
provider_urls | مورد نیاز است | آرایه ای از مسیرهای فایل پیکربندی IdP. اگر accounts_endpoint و login_url مشخص شده باشد، نادیده گرفته میشود (اما همچنان لازم است). |
accounts_endpoint | توصیه می شود، به login_url نیاز دارد | URL برای نقطه پایانی حساب ها. تا زمانی که هر فایل پیکربندی از URL login_url و accounts_endpoint یکسان استفاده کند، این امکان پشتیبانی از پیکربندی چندگانه را فراهم میکند.توجه: این پارامتر از Chrome 132 پشتیبانی میشود. |
login_url | توصیه می شود، به accounts_endpoint نیاز دارد | آدرس صفحه ورود به سیستم برای ورود کاربر به IdP. تا زمانی که هر فایل پیکربندی از همان login_url و accounts_endpoint استفاده کند، این امکان پشتیبانی از پیکربندی چندگانه را فراهم میکند.توجه: این پارامتر از Chrome 132 به بعد پشتیبانی میشود. |
به عنوان مثال، اگر نقاط پایانی IdP تحت https://accounts.idp.example/
ارائه می شوند، باید یک فایل شناخته شده در https://idp.example/.well-known/web-identity
و همچنین یک فایل ارائه دهند. فایل پیکربندی IdP . در اینجا یک نمونه از محتوای فایل معروف است:
{
"provider_urls": ["https://accounts.idp.example/config.json"]
}
IdP ها می توانند چندین فایل پیکربندی را برای یک IdP با مشخص کردن accounts_endpoint
و login_url
در فایل شناخته شده در خود جای دهند.
این ویژگی می تواند در موارد زیر مفید باشد:
- یک IdP باید از چندین پیکربندی مختلف تست و تولید پشتیبانی کند.
- یک IdP نیاز به پشتیبانی از پیکربندی های مختلف در هر منطقه دارد (به عنوان مثال،
eu-idp.example
وus-idp.example
).
برای پشتیبانی از تنظیمات متعدد (مثلاً برای تمایز بین محیط آزمایش و تولید)، IdP باید accounts_endpoint
و login_url
مشخص کند:
{
// This property is required, but will be ignored when IdP supports
// multiple configs (when `accounts_endpoint` and `login_url` are
// specified), as long as `accounts_endpoint` and `login_url` in
// that config file match those in the well-known file.
"provider_urls": [ "https://idp.example/fedcm.json" ],
// Specify accounts_endpoint and login_url properties to support
// multiple config files.
// Note: The accounts_endpoint and login_url must be identical
// across all config files. Otherwise,
// the configurations won't be supported.
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
یک فایل پیکربندی IdP و نقاط پایانی ایجاد کنید
فایل پیکربندی IdP لیستی از نقاط پایانی مورد نیاز برای مرورگر را ارائه می دهد. IdP ها باید یک یا چند فایل پیکربندی، و نقاط پایانی و URL های مورد نیاز را میزبانی کنند. همه پاسخهای JSON باید با نوع محتوای application/json
ارائه شوند.
URL فایل پیکربندی با مقادیر ارائه شده به فراخوانی navigator.credentials.get()
اجرا شده در RP تعیین می شود.
const credential = await navigator.credentials.get({
identity: {
context: 'signup',
providers: [{
configURL: 'https://accounts.idp.example/config.json',
clientId: '********',
nonce: '******'
}]
}
});
const { token } = credential;
RP URL فایل پیکربندی را به فراخوانی API FedCM ارسال می کند تا به کاربر اجازه ورود به سیستم را بدهد:
// Executed on RP's side:
const credential = await navigator.credentials.get({
identity: {
context: 'signup',
providers: [{
// To allow users to sign in with an IdP using FedCM, RP specifies the IdP's config file URL:
configURL: 'https://accounts.idp.example/fedcm.json',
clientId: '********',
});
const { token } = credential;
مرورگر فایل پیکربندی را با درخواست GET
بدون سرصفحه Origin
یا Referer
دریافت می کند. درخواست کوکی ندارد و از تغییر مسیرها پیروی نمی کند. این به طور موثری از IdP جلوگیری میکند که بفهمد چه کسی درخواست را انجام داده و کدام RP را در تلاش برای اتصال است. به عنوان مثال:
GET /config.json HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity
IdP باید یک نقطه پایانی پیکربندی را پیاده سازی کند که با JSON پاسخ دهد. JSON دارای ویژگی های زیر است:
اموال | توضیحات |
---|---|
accounts_endpoint (الزامی) | URL برای نقطه پایانی حسابها . |
accounts.include (اختیاری) | رشته برچسب حساب سفارشی، تعیین می کند که چه حساب هایی باید هنگام استفاده از این فایل پیکربندی برگردانده شوند، به عنوان مثال: "accounts": {"include": "developer"} .یک IdP می تواند برچسب گذاری حساب سفارشی را به صورت زیر پیاده سازی کند:
برای مثال، یک IdP فایل پیکربندی "https://idp.example/developer-config.json" با "accounts": {"include": "developer"} مشخص شده پیاده سازی می کند. IdP همچنین برخی از حساب ها را با برچسب "developer" با استفاده از پارامتر labels در نقطه پایانی حساب ها علامت گذاری می کند. وقتی یک RP navigator.credentials.get() با فایل پیکربندی "https://idp.example/developer-config.json" فراخوانی میکند، فقط حسابهایی با برچسب "developer" بازگردانده میشوند. |
client_metadata_endpoint (اختیاری) | URL برای نقطه پایانی فراداده مشتری . |
id_assertion_endpoint (الزامی) | URL برای نقطه پایانی ادعای شناسه . |
disconnect (اختیاری) | URL برای نقطه پایانی قطع ارتباط . |
login_url (الزامی) | آدرس صفحه ورود به سیستم برای ورود کاربر به IdP. |
branding (اختیاری) | شیئی که شامل گزینه های مختلف برندسازی است. |
branding.background_color (اختیاری) | گزینه برندینگ که رنگ پسزمینه دکمه «ادامه بهعنوان...» را تنظیم میکند. از نحو CSS مربوطه، یعنی hex-color ، hsl() rgb() یا named-color استفاده کنید. |
branding.color (اختیاری) | گزینه برندینگ که رنگ متن دکمه "ادامه به عنوان..." را تنظیم می کند. از نحو CSS مربوطه، یعنی hex-color ، hsl() rgb() یا named-color استفاده کنید. |
branding.icons (اختیاری) | آرایه ای از اشیاء نماد. این نمادها در گفتگوی ورود به سیستم نمایش داده می شوند. شی نماد دارای دو پارامتر است:
|
modes | شیئی که حاوی مشخصات نحوه نمایش رابط کاربری FedCM در حالت های مختلف است:
|
modes.active | شیء حاوی ویژگی هایی که امکان سفارشی سازی رفتار FedCM را در یک حالت خاص فراهم می کند. هر دو modes.active و modes.passive می توانند شامل پارامتر زیر باشند:
توجه: از ویژگی سایر حسابها استفاده کنید و حالت فعال از Chrome 132 پشتیبانی میشود. |
modes.passive |
در اینجا یک نمونه بدن پاسخ از IdP آمده است:
{
"accounts_endpoint": "/accounts.example",
"client_metadata_endpoint": "/client_metadata.example",
"id_assertion_endpoint": "/assertion.example",
"disconnect_endpoint": "/disconnect.example",
"login_url": "/login",
// When RPs use this config file, only those accounts will be
//returned that include `developer` label in the accounts endpoint.
"accounts": {"include": "developer"},
"modes": {
"active": {
"supports_use_other_account": true,
}
},
"branding": {
"background_color": "green",
"color": "#FFEEAA",
"icons": [{
"url": "https://idp.example/icon.ico",
"size": 25
}]
}
}
هنگامی که مرورگر فایل پیکربندی را واکشی می کند، درخواست های بعدی را به نقاط پایانی IdP ارسال می کند:
از حساب دیگر استفاده کنید
اگر IdP از چندین حساب پشتیبانی می کند یا حساب موجود را جایگزین می کند، کاربران می توانند به حسابی تغییر کنند که با حسابی که در حال حاضر با آن وارد شده اند متفاوت است.
برای اینکه کاربر بتواند حساب های دیگر را انتخاب کند، IdP باید این ویژگی را در فایل پیکربندی مشخص کند:
{
"accounts_endpoint" : "/accounts.example",
"modes": {
"active": {
// Allow the user to choose other account (false by default)
"supports_use_other_account": true
}
// "passive" mode can be configured separately
}
}
نقطه پایانی حساب ها
نقطه پایانی حسابهای IdP فهرستی از حسابهایی را که کاربر در IdP وارد شده است، برمیگرداند. اگر IdP از چندین حساب پشتیبانی کند، این نقطه پایانی همه حسابهای وارد شده را برمیگرداند.
مرورگر یک درخواست GET
را با کوکیهایی با SameSite=None
ارسال میکند، اما بدون پارامتر client_id
، سرصفحه Origin
یا Referer
. این به طور موثری از IdP جلوگیری می کند تا یاد بگیرد که کاربر قصد دارد به کدام RP وارد شود. به عنوان مثال:
GET /accounts.example HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
پس از دریافت درخواست، سرور باید:
- بررسی کنید که درخواست حاوی سرصفحه HTTP
Sec-Fetch-Dest: webidentity
باشد. - کوکیهای جلسه را با شناسههای حسابهایی که قبلاً وارد سیستم شدهاند مطابقت دهید.
- با لیست حساب ها پاسخ دهید.
مرورگر انتظار پاسخ JSON را دارد که شامل یک ویژگی accounts
با آرایه ای از اطلاعات حساب با ویژگی های زیر است:
اموال | توضیحات |
---|---|
id (الزامی) | شناسه منحصر به فرد کاربر |
name (الزامی) | نام و نام خانوادگی کاربر. |
email (الزامی) | آدرس ایمیل کاربر. |
given_name (اختیاری) | نام کاربر. |
picture (اختیاری) | URL تصویر آواتار کاربر. |
approved_clients (اختیاری) | آرایه ای از شناسه های مشتری RP که کاربر با آن ثبت نام کرده است. |
login_hints (اختیاری) | آرایه ای از انواع فیلترهای ممکن که IdP برای تعیین یک حساب پشتیبانی می کند. RP می تواند navigator.credentials.get() با ویژگی loginHint فراخوانی کند تا به صورت انتخابی حساب مشخص شده را نشان دهد. |
domain_hints (اختیاری) | آرایه ای از تمام دامنه هایی که حساب با آنها مرتبط است. RP میتواند navigator.credentials.get() با ویژگی domainHint فراخوانی کند تا حسابها را فیلتر کند. |
labels (اختیاری) | آرایهای از رشتهها برچسبهای حساب سفارشی که یک حساب با آنها مرتبط است. یک IdP می تواند برچسب گذاری حساب سفارشی را به صورت زیر پیاده سازی کند:
به عنوان مثال، یک IdP فایل پیکربندی https://idp.example/developer-config.json را با مشخص کردن "accounts": {"include": "developer"} پیاده سازی می کند. IdP همچنین برخی از حساب ها را با برچسب "developer" با استفاده از پارامتر labels در نقطه پایانی حساب ها علامت گذاری می کند. وقتی یک RP navigator.credentials.get() با فایل پیکربندی https://idp.example/developer-config.json فراخوانی میکند، فقط حسابهایی با برچسب "developer" بازگردانده میشوند.برچسبهای حساب سفارشی با راهنمای ورود و اشاره دامنه متفاوت هستند به گونهای که به طور کامل توسط سرور IdP نگهداری میشوند و RP فقط فایل پیکربندی مورد استفاده را مشخص میکند. |
نمونه بدن پاسخ:
{
"accounts": [{
"id": "1234",
"given_name": "John",
"name": "John Doe",
"email": "john_doe@idp.example",
"picture": "https://idp.example/profile/123",
// Ids of those RPs where this account can be used
"approved_clients": ["123", "456", "789"],
// This account has 'login_hints`. When an RP calls `navigator.credentials.get()`
// with a `loginHint` value specified, for example, `exampleHint`, only those
// accounts will be shown to the user whose 'login_hints' array contains the `exampleHint`.
"login_hints": ["demo1", "exampleHint"],
// This account is labelled. IdP can implement a specific config file for a
// label, for example, `https://idp.example/developer-config.json`. Like that
// RPs can filter out accounts by calling `navigator.credentials.get()` with
// `https://idp.example/developer-config.json` config file.
"labels": ["hr", "developer"]
}, {
"id": "5678",
"given_name": "Johnny",
"name": "Johnny",
"email": "johnny@idp.example",
"picture": "https://idp.example/profile/456",
"approved_clients": ["abc", "def", "ghi"],
"login_hints": ["demo2"],
"domain_hints": ["@domain.example"]
}]
}
اگر کاربر وارد سیستم نشده است، با HTTP 401
(غیر مجاز) پاسخ دهید.
لیست حساب های برگشتی توسط مرورگر مصرف می شود و برای RP در دسترس نخواهد بود.
نقطه پایان ادعای شناسه
نقطه پایانی ادعای شناسه IdP یک ادعا را برای کاربر واردشده به سیستم باز میگرداند. هنگامی که کاربر با استفاده از فراخوان navigator.credentials.get()
وارد یک وب سایت RP می شود، مرورگر یک درخواست POST
با کوکی هایی با SameSite=None
و یک نوع محتوا از application/x-www-form-urlencoded
به این نقطه پایانی ارسال می کند. اطلاعات زیر:
اموال | توضیحات |
---|---|
client_id (الزامی) | شناسه مشتری RP. |
account_id (الزامی) | شناسه منحصر به فرد کاربر در حال ورود به سیستم. |
disclosure_text_shown | نتیجه در یک رشته "true" یا "false" (به جای یک بولی). نتیجه در این موارد "false" است:
|
is_auto_selected | اگر احراز هویت مجدد خودکار در RP انجام شود، is_auto_selected نشان دهنده "true" است. در غیر این صورت "false" . این برای پشتیبانی بیشتر از ویژگی های مرتبط با امنیت مفید است. به عنوان مثال، برخی از کاربران ممکن است سطح امنیتی بالاتری را ترجیح دهند که نیاز به میانجیگری صریح کاربر در احراز هویت دارد. اگر یک IdP یک درخواست توکن را بدون چنین میانجیگری دریافت کند، میتواند درخواست را به گونهای متفاوت مدیریت کند. به عنوان مثال، یک کد خطایی را برگردانید به طوری که RP بتواند دوباره FedCM API را با mediation: required . |
fields (اختیاری) | آرایهای از رشتهها که اطلاعات کاربر ("نام"، "ایمیل"، "تصویر") را مشخص میکند که RP به IdP نیاز دارد تا با آنها به اشتراک بگذارد. مرورگر fields disclosure_text_shown و disclosure_shown_for برای فهرست کردن فیلدهای مشخص شده در درخواست POST ارسال میکند، مانند مثال زیر .توجه: پارامتر فیلدها از Chrome 132 پشتیبانی میشود. |
params (اختیاری) | هر شیء JSON معتبری که امکان تعیین پارامترهای کلیدی سفارشی اضافی را فراهم می کند، به عنوان مثال:
params به JSON سریال می شود و سپس با درصد رمزگذاری می شود .توجه: Parameters API توسط Chrome 132 و جدیدتر پشتیبانی میشود. |
هدر HTTP مثال:
POST /assertion.example HTTP/1.1
Host: accounts.idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
// disclosure_text_shown is set to 'false', as the 'name' field value is missing in 'fields' array
// params value is serialized to JSON and then percent-encoded.
account_id=123&client_id=client1234&disclosure_text_shown=false&is_auto_selected=true¶ms=%22%7B%5C%22nonce%5C%22%3A%5C%22nonce-value%5C%22%7D%22.%0D%0A4&disclosure_text_shown=true&fields=email,picture&disclosure_shown_for=email,picture
پس از دریافت درخواست، سرور باید:
- با CORS (اشتراک گذاری منابع متقابل) به درخواست پاسخ دهید.
- بررسی کنید که درخواست حاوی سرصفحه HTTP
Sec-Fetch-Dest: webidentity
باشد. - سرصفحه
Origin
را با مبدا RP تعیین شده توسطclient_id
مطابقت دهید. اگر مطابقت نداشتند رد کنید. -
account_id
با شناسه حسابی که قبلاً وارد سیستم شدهاید مطابقت دهید. اگر مطابقت نداشتند رد کنید. - با یک نشانه پاسخ دهید. اگر درخواست رد شد، با یک پاسخ خطا پاسخ دهید.
IdP می تواند تصمیم بگیرد که چگونه توکن را صادر کند. به طور کلی، با اطلاعاتی مانند شناسه حساب، شناسه مشتری، مبدأ صادرکننده و nonce امضا شده است تا RP بتواند اصل بودن توکن را تأیید کند.
مرورگر انتظار پاسخ JSON را دارد که شامل ویژگی زیر است:
اموال | توضیحات |
---|---|
token | توکن رشتهای است که حاوی ادعاهایی درباره احراز هویت است. |
continue_on | تغییر مسیر URL که یک جریان ورود به سیستم چند مرحله ای را فعال می کند. |
توکن برگشتی توسط مرورگر به RP ارسال می شود تا RP بتواند احراز هویت را تأیید کند.
{
// IdP can respond with a token to authenticate the user
"token": "***********"
}
ادامه روی ویژگی
IdP میتواند یک URL تغییر مسیر در پاسخ نقطه پایانی ادعای ID برای فعال کردن یک جریان ورود چند مرحلهای ارائه کند. این زمانی مفید است که IdP نیاز به درخواست اطلاعات یا مجوزهای اضافی داشته باشد، به عنوان مثال:
- اجازه دسترسی به منابع سمت سرور کاربر.
- تأیید اینکه اطلاعات تماس به روز هستند.
- کنترل های والدین
نقطه پایانی ادعای ID میتواند یک ویژگی continue_on
را برگرداند که شامل یک مسیر مطلق یا نسبی به نقطه پایانی ادعای ID است.
{
// In the id_assertion_endpoint, instead of returning a typical
// "token" response, the IdP decides that it needs the user to
// continue on a popup window:
"continue_on": "https://idp.example/continue_on_url"
}
اگر پاسخ حاوی پارامتر continue_on
باشد، یک پنجره بازشو باز می شود و کاربر را به مسیر مشخص شده هدایت می کند. پس از تعامل کاربر با صفحه continue_on
، IdP باید IdentityProvider.resolve()
با توکن ارسال شده به عنوان آرگومان فراخوانی کند تا وعده فراخوانی navigator.credentials.get()
اصلی حل شود:
document.getElementById('example-button').addEventListener('click', async () => {
let accessToken = await fetch('/generate_access_token.cgi');
// Closes the window and resolves the promise (that is still hanging
// in the relying party's renderer) with the value that is passed.
IdentityProvider.resolve(accessToken);
});
سپس مرورگر به طور خودکار پنجره بازشو را می بندد و توکن را به تماس گیرنده API برمی گرداند. فراخوانی یکباره IdentityProvider.resolve()
تنها راه ارتباط بین پنجره والد (RP) و پنجره بازشو (IdP) است.
اگر کاربر درخواست را رد کند، IdP میتواند با فراخوانی IdentityProvider.close()
پنجره را ببندد.
IdentityProvider.close();
Continuation API برای عملکرد به تعامل صریح کاربر (کلیکها) نیاز دارد. در اینجا نحوه عملکرد Continuation API با حالتهای مختلف میانجیگری آمده است:
- در حالت غیرفعال :
-
mediation: 'optional'
(پیشفرض): Continuation API فقط با اشاره کاربر کار میکند، مانند کلیک کردن روی دکمهای در صفحه یا روی رابط کاربری FedCM. هنگامی که احراز هویت مجدد خودکار بدون اشاره کاربر راه اندازی می شود، هیچ پنجره بازشوی باز نمی شود و وعده رد می شود. -
mediation: 'required'
: همیشه از کاربر میخواهد تعامل داشته باشد، بنابراین Continuation API همیشه کار میکند.
-
- در حالت فعال :
- فعال سازی کاربر همیشه مورد نیاز است. Continuation API سازگار است.
اگر به دلایلی کاربر حساب خود را در پنجره بازشو تغییر داده باشد (به عنوان مثال، IdP یک تابع "استفاده از حساب دیگر" یا در موارد تفویض اختیار را ارائه می دهد)، فراخوانی حل یک آرگومان دوم اختیاری را می گیرد که اجازه می دهد چیزی شبیه به:
IdentityProvider.resolve(token, {accountId: '1234');
پاسخ خطا را برگردانید
id_assertion_endpoint
همچنین می تواند یک پاسخ "خطا" را برگرداند که دارای دو فیلد اختیاری است:
-
code
: IdP می تواند یکی از خطاهای شناخته شده را از لیست خطاهای مشخص شده OAuth 2.0 (invalid_request
،unauthorized_client
،access_denied
،server_error
وtemporarily_unavailable
) انتخاب کند یا از هر رشته دلخواه استفاده کند. اگر مورد دوم باشد، Chrome رابط کاربری خطا را با یک پیام خطای عمومی ارائه میکند و کد را به RP ارسال میکند. -
url
: یک صفحه وب قابل خواندن توسط انسان را با اطلاعات مربوط به خطا شناسایی می کند تا اطلاعات بیشتری در مورد خطا به کاربران ارائه دهد. این فیلد برای کاربران مفید است زیرا مرورگرها نمی توانند پیام های خطای غنی را در یک رابط کاربری داخلی ارائه دهند. به عنوان مثال: پیوندهایی برای مراحل بعدی، یا اطلاعات تماس خدمات مشتری. اگر کاربر میخواهد درباره جزئیات خطا و نحوه رفع آن اطلاعات بیشتری کسب کند، میتواند برای جزئیات بیشتر به صفحه ارائه شده از رابط کاربری مرورگر مراجعه کند. URL باید همان سایتی باشد که IdPconfigURL
.
// id_assertion_endpoint response
{
"error" : {
"code": "access_denied",
"url" : "https://idp.example/error?type=access_denied"
}
}
برچسب های حساب سفارشی
با برچسبهای حساب سفارشی ، IdP میتواند حسابهای کاربری را با برچسبها حاشیهنویسی کند، و RP میتواند تنها با تعیین configURL
برای آن برچسب خاص، حسابهایی را با برچسبهای خاص واکشی کند. این می تواند زمانی مفید باشد که یک RP نیاز به فیلتر کردن حساب ها با معیارهای خاص داشته باشد، به عنوان مثال، فقط برای نمایش حساب های خاص نقش مانند "developer"
یا "hr"
.
فیلتر مشابهی با استفاده از ویژگی Domain Hint و Login Hint ، با مشخص کردن آنها در فراخوانی navigator.credentials.get()
امکان پذیر است. با این حال، برچسبهای حساب سفارشی میتوانند با مشخص کردن فایل پیکربندی، کاربران را فیلتر کنند، که مخصوصاً وقتی از چندین configURL استفاده میشود، مفید است. برچسبهای حساب سفارشی نیز از این جهت متفاوت هستند که از سرور IdP ارائه میشوند، برخلاف RP، مانند نکات ورود به سیستم یا دامنه.
یک IdP را در نظر بگیرید که میخواهد بین حسابهای "developer"
و "hr"
تفاوت قائل شود. برای دستیابی به این هدف، IdP نیاز به پشتیبانی از دو configURL برای "developer"
و "hr"
دارد:
- فایل پیکربندی برنامهنویس
https://idp.example/developer/fedcm.json
دارای برچسب"developer"
و فایل پیکربندی سازمانیhttps://idp.example/hr/fedcm.json
دارای برچسب"hr"
به شرح زیر است. :
// The developer config file at `https://idp.example/developer/fedcm.json`
{
"accounts_endpoint": "https://idp.example/accounts",
"client_metadata_endpoint": "/client_metadata",
"login_url": "https://idp.example/login",
"id_assertion_endpoint": "/assertion",
"accounts": {
// Account label
"include": "developer"
}
}
// The hr config file at `https://idp.example/hr/fedcm.json`
{
"accounts_endpoint": "https://idp.example/accounts",
"client_metadata_endpoint": "/client_metadata",
"login_url": "https://idp.example/login",
"id_assertion_endpoint": "/assertion",
"accounts": {
// Account label
"include": "hr"
}
}
- با چنین تنظیماتی، فایل شناخته شده باید شامل
accounts_endpoint
وlogin_url
باشد تا چندین configURL مجاز باشد:
{
"provider_urls": [ "https://idp.example/fedcm.json" ],
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
- نقطه پایانی مشترک حسابهای IdP (در این مثال
https://idp.example/accounts
) فهرستی از حسابها را برمیگرداند که شامل یک ویژگیlabels
با برچسبهای اختصاص داده شده در یک آرایه برای هر حساب است:
{
"accounts": [{
"id": "123",
"given_name": "John",
"name": "John Doe",
"email": "john_doe@idp.example",
"picture": "https://idp.example/profile/123",
"labels": ["developer"]
}], [{
"id": "4567",
"given_name": "Jane",
"name": "Jane Doe",
"email": "jane_doe@idp.example",
"picture": "https://idp.example/profile/4567",
"labels": ["hr"]
}]
}
هنگامی که یک RP می خواهد به کاربران "hr"
اجازه ورود به سیستم را بدهد، می توانند configURL https://idp.example/hr/fedcm.json
را در فراخوانی navigator.credentials.get()
مشخص کنند:
let { token } = await navigator.credentials.get({
identity: {
providers: [{
clientId: '1234',
nonce: '234234',
configURL: 'https://idp.example/hr/fedcm.json',
},
}
});
در نتیجه، فقط شناسه حساب 4567
برای ورود کاربر در دسترس است. شناسه حساب 123
بهطور بیصدا توسط مرورگر پنهان میشود تا حسابی به کاربر ارائه نشود که توسط IdP در این مورد پشتیبانی نمیشود. سایت
- برچسب ها رشته هستند. اگر آرایه
labels
یا فیلدinclude
چیزی باشد که رشته نیست، نادیده گرفته میشود. - اگر هیچ برچسبی در
configURL
مشخص نشده باشد، همه حساب ها در انتخابگر حساب FedCM نمایش داده می شوند. - اگر هیچ برچسبی برای یک حساب مشخص نشده باشد، تنها در صورتی در انتخابگر حساب نمایش داده می شود که
configURL
نیز برچسبی را مشخص نکرده باشد. - اگر هیچ حسابی با برچسب درخواستی در حالت غیرفعال مطابقت نداشته باشد (شبیه به ویژگی Domain Hint)، کادر گفتگوی FedCM یک اعلان ورود به سیستم را نشان می دهد که به کاربر اجازه می دهد به یک حساب IdP وارد شود. برای حالت فعال، پنجره بازشوی ورود مستقیماً باز می شود.
نقطه پایانی را قطع کنید
با فراخوانی IdentityCredential.disconnect()
، مرورگر یک درخواست POST
متقاطع را با کوکی هایی با SameSite=None
و یک نوع محتوا از application/x-www-form-urlencoded
به این نقطه پایانی قطع با اطلاعات زیر ارسال می کند:
اموال | توضیحات |
---|---|
account_hint | راهنمایی برای حساب IdP.. |
client_id | شناسه مشتری RP. |
POST /disconnect.example HTTP/1.1
Host: idp.example
Origin: rp.example
Content-Type: application/x-www-form-urlencoded
Cookie: 0x123
Sec-Fetch-Dest: webidentity
account_hint=account456&client_id=rp123
پس از دریافت درخواست، سرور باید:
- با CORS (اشتراک گذاری منابع متقابل) به درخواست پاسخ دهید.
- بررسی کنید که درخواست حاوی سرصفحه HTTP
Sec-Fetch-Dest: webidentity
باشد. - سرصفحه
Origin
را با مبدا RP تعیین شده توسطclient_id
مطابقت دهید. اگر مطابقت نداشتند رد کنید. -
account_hint
با شناسههای حسابهایی که قبلاً وارد سیستم شدهاند مطابقت دهید. - حساب کاربری را از RP جدا کنید.
- با اطلاعات حساب کاربری شناسایی شده در قالب JSON به مرورگر پاسخ دهید.
یک نمونه پاسخ JSON payload به این صورت است:
{
"account_id": "account456"
}
در عوض، اگر IdP بخواهد مرورگر همه حسابهای مرتبط با RP را قطع کند، رشتهای را ارسال کنید که با هیچ شناسه حسابی مطابقت ندارد، به عنوان مثال "*"
.
نقطه پایانی فراداده مشتری
نقطه پایانی فراداده مشتری IdP، فراداده طرف متکی را مانند خطمشی رازداری RP، شرایط خدمات، و نمادهای نشانواره را برمیگرداند. RP ها باید پیوندهایی به خط مشی رازداری و شرایط خدمات خود را از قبل در اختیار IdP قرار دهند. زمانی که کاربر هنوز در RP با IdP ثبت نام نکرده باشد، این پیوندها در گفتگوی ورود به سیستم نمایش داده می شوند.
مرورگر یک درخواست GET
را با استفاده از client_id
navigator.credentials.get
بدون کوکی ارسال می کند. به عنوان مثال:
GET /client_metadata.example?client_id=1234 HTTP/1.1
Host: accounts.idp.example
Origin: https://rp.example/
Accept: application/json
Sec-Fetch-Dest: webidentity
پس از دریافت درخواست، سرور باید:
- RP را برای
client_id
تعیین کنید. - با فراداده مشتری پاسخ دهید.
ویژگیهای نقطه پایانی فراداده مشتری عبارتند از:
اموال | توضیحات |
---|---|
privacy_policy_url (اختیاری) | URL خط مشی رازداری RP. |
terms_of_service_url (اختیاری) | URL شرایط خدمات RP. |
icons (اختیاری) | آرایه ای از اشیاء، مانند [{ "url": "https://rp.example/rp-icon.ico", "size": 40}] |
مرورگر انتظار پاسخ JSON را از نقطه پایانی دارد:
{
"privacy_policy_url": "https://rp.example/privacy_policy.html",
"terms_of_service_url": "https://rp.example/terms_of_service.html",
"icons": [{
"url": "https://rp.example/rp-icon.ico",
"size": 40
}]
}
ابرداده مشتری برگشتی توسط مرورگر مصرف می شود و برای RP در دسترس نخواهد بود.
URL ورود
این نقطه پایانی برای اجازه ورود کاربر به IdP استفاده می شود.
با Login Status API ، IdP باید وضعیت ورود کاربر را به مرورگر اطلاع دهد. با این حال، وضعیت ممکن است هماهنگ نباشد، مانند زمانی که جلسه منقضی شود . در چنین سناریویی، مرورگر می تواند به صورت پویا به کاربر اجازه دهد از طریق 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
(پیش فرض)
وضعیت ورود | توضیحات |
---|---|
logged-in | هنگامی که وضعیت ورود کاربر به logged-in است، RP که FedCM را فرا میخواند، درخواستهایی را به نقطه پایانی حسابهای IdP میدهد و حسابهای موجود را در گفتگوی FedCM به کاربر نمایش میدهد. |
logged-out | هنگامی که وضعیت ورود به سیستم کاربر logged-out میشود، فراخوانی FedCM بیصدا بدون درخواست به نقطه پایانی حسابهای IdP انجام نمیشود. |
unknown (پیش فرض) | وضعیت unknown قبل از ارسال سیگنال توسط IdP با استفاده از Login Status API تنظیم می شود. هنگامی که وضعیت unknown است، مرورگر درخواستی به نقطه پایانی حسابهای IdP میدهد و وضعیت را بر اساس پاسخ نقطه پایانی حسابها بهروزرسانی میکند. |
برای نشان دادن اینکه کاربر وارد سیستم شده است، یک سرصفحه HTTP Set-Login: logged-in
در یک ناوبری سطح بالا یا یک درخواست منبع فرعی همان سایت در مبدا IdP ارسال کنید:
Set-Login: logged-in
روش دیگر، روش جاوا اسکریپت navigator.login.setStatus('logged-in')
از مبدا IdP در یک ناوبری سطح بالا فراخوانی کنید:
navigator.login.setStatus('logged-in')
وضعیت ورود به سیستم کاربر به عنوان logged-in
تنظیم می شود.
برای نشان دادن اینکه کاربر از همه حسابهای خود خارج شده است، یک سرصفحه HTTP Set-Login: logged-out
در یک ناوبری سطح بالا یا یک درخواست منبع فرعی همان سایت در مبدا IdP ارسال کنید:
Set-Login: logged-out
همچنین، JavaScript API navigator.login.setStatus('logged-out')
از مبدا IdP در یک ناوبری سطح بالا فراخوانی کنید:
navigator.login.setStatus('logged-out')
وضعیت ورود به سیستم کاربر به عنوان logged-out
تنظیم می شود.
وضعیت unknown
قبل از ارسال سیگنال توسط IdP با استفاده از Login Status API تنظیم می شود. مرورگر به نقطه پایانی حسابهای IdP درخواست میکند و وضعیت را براساس پاسخ نقطه پایانی حسابها بهروزرسانی میکند:
- اگر نقطه پایانی فهرستی از حسابهای فعال را برمیگرداند، وضعیت را به
logged-in
بهروزرسانی کنید و کادر گفتگوی FedCM را برای نمایش آن حسابها باز کنید. - اگر نقطه پایانی هیچ حسابی برگرداند، وضعیت را به
logged-out
بهروزرسانی کنید و تماس FedCM ناموفق باشد.
به کاربر اجازه دهید از طریق یک جریان ورود پویا وارد سیستم شود
حتی اگر IdP وضعیت ورود کاربر به مرورگر را به اطلاع میرساند، ممکن است مانند زمانی که جلسه منقضی میشود، هماهنگ نباشد. هنگامی که وضعیت ورود به سیستم logged-in
است، مرورگر سعی میکند یک درخواست اعتبارسنجی را به نقطه پایانی حسابها ارسال کند، اما سرور هیچ حسابی برمیگرداند زیرا جلسه دیگر در دسترس نیست. در چنین سناریویی، مرورگر میتواند به صورت پویا به کاربر اجازه دهد از طریق یک پنجره بازشو به IdP وارد شود .
FedCM را به عنوان RP پیاده سازی کنید
هنگامی که پیکربندی و نقاط پایانی IdP در دسترس هستند، RP ها می توانند با فراخوانی navigator.credentials.get()
درخواست کنند تا کاربران بتوانند با IdP وارد RP شوند.
قبل از تماس با API، باید تأیید کنید که FedCM در مرورگر کاربر در دسترس است . برای بررسی اینکه آیا FedCM در دسترس است، این کد را در اطراف پیاده سازی FedCM خود بپیچید:
if ('IdentityCredential' in window) {
// If the feature is available, take action
} else {
// FedCM is not supported, use a different identity solution
}
برای اینکه کاربران بتوانند با استفاده از FedCM وارد IdP در یک RP شوند، RP میتواند navigator.credentials.get()
را فراخوانی کند، برای مثال:
const credential = await navigator.credentials.get({
identity: {
context: 'signin',
providers: [{
configURL: 'https://accounts.idp.example/config.json',
clientId: '********',
mode: 'active',
params: {
nonce: '******'
}
}]
}
});
const { token } = credential;
ویژگی زمینه
با ویژگی context
اختیاری، RP میتواند رشته را در رابط کاربری گفتگوی FedCM تغییر دهد (به عنوان مثال، "ورود به rp.example..."، "استفاده از idp.example...") تا برای مثال، زمینههای احراز هویت از پیش تعریف شده را در خود جای دهد. ویژگی context
می تواند مقادیر زیر را داشته باشد:
-
signin
(پیش فرض) -
signup
-
use
به عنوان مثال، تنظیم context
برای use
پیام زیر را به همراه خواهد داشت:
مرورگر بسته به وجود approved_clients
در پاسخ از نقطه پایانی فهرست حسابها، موارد استفاده از ثبت نام و ورود به سیستم را متفاوت مدیریت میکند. اگر کاربر قبلاً در RP ثبت نام کرده باشد، مرورگر متن افشای «برای ادامه با ...» را نمایش نمی دهد.
ویژگی providers
آرایه ای از اشیاء IdentityProvider را می گیرد که دارای ویژگی های زیر هستند:
اموال را ارائه می دهد
ویژگی providers
آرایه ای از اشیاء IdentityProvider
را می گیرد که دارای ویژگی های زیر هستند:
اموال | توضیحات |
---|---|
configURL (الزامی) | مسیر کامل فایل پیکربندی IdP. |
clientId (الزامی) | شناسه مشتری RP، صادر شده توسط IdP. |
nonce (اختیاری) | یک رشته تصادفی برای اطمینان از صدور پاسخ برای این درخواست خاص. از حملات تکراری جلوگیری می کند. |
loginHint (اختیاری) | با مشخص کردن یکی از مقادیر login_hints ارائه شده توسط نقاط پایانی حساب ها ، گفتگوی FedCM به صورت انتخابی حساب مشخص شده را نشان می دهد. |
domainHint (اختیاری) | با مشخص کردن یکی از مقادیر domain_hints ارائه شده توسط نقاط پایانی حساب ها ، گفتگوی FEDCM به طور انتخابی حساب مشخص شده را نشان می دهد. |
mode (اختیاری) | رشته ای که حالت UI FEDCM را مشخص می کند. این می تواند یکی از این مقادیر باشد:
توجه: پارامتر mode از Chrome 132 پشتیبانی می شود. |
fields (اختیاری) | مجموعه ای از رشته هایی که اطلاعات کاربر را مشخص می کند ("نام" ، "ایمیل" ، "تصویر") که RP برای به اشتراک گذاشتن با آنها به IDP نیاز دارد. توجه: API فیلد توسط Chrome 132 و بعد از آن پشتیبانی می شود. |
parameters (اختیاری) | شیء سفارشی که امکان مشخص کردن پارامترهای اضافی با ارزش کلید را فراهم می کند:
توجه: parameters از Chrome 132 پشتیبانی می شوند. |
حالت فعال
FEDCM از تنظیمات مختلف حالت UX پشتیبانی می کند. حالت غیرفعال حالت پیش فرض است و توسعه دهندگان نیازی به پیکربندی آن ندارند.
برای استفاده از FEDCM در حالت فعال:
- در دسترس بودن ویژگی در مرورگر کاربر را بررسی کنید.
- API را با یک ژست کاربر گذرا ، مانند کلیک بر روی دکمه ، فراخوانی کنید.
- پارامتر
mode
را به تماس API منتقل کنید:
let supportsFedCmMode = false;
try {
navigator.credentials.get({
identity: Object.defineProperty(
// Check if this Chrome version supports the Mode API.
{}, 'mode', {
get: function () { supportsFedCmMode = true; }
}
)
});
} catch(e) {}
if (supportsFedCmMode) {
// The button mode is supported. Call the API with mode property:
return await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/config.json',
clientId: '123',
}],
// The 'mode' value defines the UX mode of FedCM.
// - 'active': Must be initiated by user interaction (e.g., clicking a button).
// - 'passive': Can be initiated without direct user interaction.
mode: 'active'
}
});
}
نماد سفارشی در حالت فعال
حالت فعال اجازه می دهد تا IDP ها نماد آرم رسمی RP را مستقیماً در پاسخ نقطه پایانی ابرداده مشتری قرار دهند. RP باید داده های مارک تجاری خود را از قبل ارائه دهد.
با 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")
شما می توانید در مورد نحوه عملکرد خط مشی مجوزها در کنترل ویژگی های مرورگر با خط مشی مجوز ، اطلاعات بیشتری کسب کنید.
ورود به سیستم API
با استفاده از اشاره ورود به سیستم ، RP می تواند توصیه کند که یک حساب کاربری باید با آن وارد شود. این می تواند برای تأیید مجدد کاربرانی که مطمئن نیستند از کدام حساب کاربری استفاده کرده اند ، مفید باشد.
RPS می تواند با فراخوانی navigator.credentials.get()
با ویژگی loginHint
با یکی از مقادیر login_hints
که از نقطه پایانی لیست حساب ها گرفته می شود ، همانطور که در نمونه کد زیر نشان داده شده است ، یک حساب خاص را به صورت انتخابی نشان دهد:
return await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/manifest.json',
clientId: '123',
// Accounts endpoint can specify a 'login_hints' array for an account.
// When RP specifies a 'exampleHint' value, only those accounts will be
// shown to the user whose 'login_hints' array contains the 'exampleHint'
// value
loginHint : 'exampleHint'
}]
}
});
هنگامی که هیچ حساب با loginHint
مطابقت نداشته باشد ، گفتگوی FEDCM سریع ورود به سیستم را نشان می دهد ، که به کاربر اجازه می دهد تا به یک حساب IDP متناسب با اشاره ای که توسط RP متناسب است ، وارد شود. هنگامی که کاربر در سریع قرار می گیرد ، یک پنجره بازشو با URL ورود به سیستم مشخص شده در پرونده پیکربندی باز می شود. پیوند سپس با پارامترهای Login Hint و Domain Hint Query ضمیمه می شود.
API Domain Hint
RPS می تواند به طور انتخابی فقط حساب های مرتبط با یک دامنه خاص را نشان دهد. این می تواند برای RP هایی که محدود به یک دامنه شرکت هستند مفید باشد.
برای نمایش فقط حسابهای دامنه خاص ، RP باید با ویژگی domainHint
با یکی از مقادیر domain_hints
که از نقطه انتهایی لیست حساب ها گرفته شده است ، با navigator.credentials.get()
تماس بگیرید ، همانطور که در نمونه کد زیر نشان داده شده است:
return await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/manifest.json',
clientId: 'abc',
// Accounts endpoint can specify a 'domain_hints' array for an account.
// When RP specifies a '@domain.example' value, only those accounts will be
// shown to the user whose 'domain_hints' array contains the
// '@domain.example' value
domainHint : '@domain.example'
}]
}
});
هنگامی که هیچ حساب با domainHint
مطابقت نداشته باشد ، گفتگوی FEDCM یک سریع ورود به سیستم را نشان می دهد ، که به کاربر اجازه می دهد تا به یک حساب IDP متناسب با اشاره ای که توسط RP درخواست شده است وارد شوید. هنگامی که کاربر در سریع قرار می گیرد ، یک پنجره بازشو با URL ورود به سیستم مشخص شده در پرونده پیکربندی باز می شود. پیوند سپس با پارامترهای Login Hint و Domain Hint Query ضمیمه می شود.
پارامترهای سفارشی
ویژگی پارامترهای سفارشی به RP اجازه می دهد تا پارامترهای ارزش کلیدی اضافی را به نقطه پایانی ادعای شناسه ارائه دهد. با استفاده از پارامترهای API ، RPS می تواند پارامترهای اضافی را به IDP منتقل کند تا مجوز منابع فراتر از ورود به سیستم اساسی را درخواست کند. عبور پارامترهای اضافی می تواند در این سناریو مفید باشد:
- RP باید مجوزهای اضافی را به صورت پویا که IDP دارد ، مانند آدرس صورتحساب یا دسترسی به تقویم ، درخواست کند. کاربر می تواند این مجوزها را از طریق جریان UX کنترل شده با IDP که با استفاده از ویژگی ادامه کار راه اندازی می شود ، مجاز کند و سپس IDP این اطلاعات را به اشتراک می گذارد.
برای استفاده از API ، RP پارامترهایی را به ویژگی params
به عنوان یک شی در navigator.credentials.get()
فراخوانی می کند: تماس:
let {token} = await navigator.credentials.get({
identity: {
providers: [{
clientId: '1234',
configURL: 'https://idp.example/fedcm.json',
// Key/value pairs that need to be passed from the
// RP to the IdP but that don't really play any role with
// the browser.
params: {
IDP_SPECIFIC_PARAM: '1',
foo: 'BAR'
}
},
}
});
مرورگر به طور خودکار این کار را به یک درخواست پست به IDP با پارامترها به عنوان یک شیء Serialized JSON- رمزگذاری شده URL انجام می دهد:
// The assertion endpoint is drawn from the config file
POST /fedcm_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
// params are translated into urlencoded version of `{"IDP_SPECIFIC_PARAM":"1","foo":"bar"}`
account_id=123&client_id=client1234¶ms=%22%7B%5C%22IDP_SPECIFIC_PARAM%5C%22%3A1%2C%5C%22foo%5C%22%3A%5C%22BAR%5C%22%7D%22.
اگر RP به مجوزهای اضافی احتیاج داشته باشد ، IDP می تواند پیوند تغییر مسیر را فراهم کند. به عنوان مثال ، در node.js:
if (rpRequestsPermissions) {
// Response with a URL if the RP requests additional permissions
return res.json({
continue_on: '/example-redirect',
});
}
فیلدها
RP می تواند اطلاعات کاربر را مشخص کند (هر ترکیبی از نام ، آدرس ایمیل و تصویر پروفایل) آنها برای به اشتراک گذاشتن با آنها به IDP نیاز دارند. اطلاعات درخواست شده در UI افشای گفتگوی FEDCM گنجانده می شود. کاربر پیامی را مشاهده می کند که به آنها اطلاع می دهد که idp.example
اطلاعات درخواستی را با rp.example
در صورت انتخاب ورود به سیستم به اشتراک می گذارد.
برای استفاده از ویژگی Fields ، RP باید یک آرایه fields
را در تماس navigator.credentials.get()
اضافه کند. این زمینه ها می توانند حاوی هرگونه تغییر name
، email
و picture
باشند. این می تواند گسترش یابد تا ارزش های بیشتری در آینده باشد. درخواست با fields
به این شکل است:
let { token } = await navigator.credentials.get({
identity: {
providers: [{
// RP requests the IdP to share only user email and profile picture
fields: [ 'email', 'picture'],
clientId: '1234',
configURL: 'https://idp.example/fedcm.json',
},
}
});
مرورگر به طور خودکار آن را به یک درخواست HTTP به نقطه پایانی ادعای ID که شامل پارامتر fields
مشخص شده RP است ، ترجمه می کند ، با زمینه هایی که مرورگر در یک پارامتر disclosure_shown_for
به کاربر افشا کرده است. برای سازگاری به عقب ، مرورگر همچنین اگر متن افشای اطلاعات نشان داده شده است ، disclosure_text_shown=true
ارسال می کند و قسمت های درخواست شده شامل هر سه قسمت است: 'name'
، 'email'
و 'picture'
.
POST /id_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
// The RP only requested to share email and picture. The browser will send `disclosure_text_shown=false`, as the 'name' field value is missing
account_id=123&client_id=client1234&disclosure_text_shown=false&fields=email,picture&disclosure_shown_for=email,picture
اگر fields
یک آرایه خالی باشد ، نماینده کاربر UI افشای اطلاعات را رد می کند.
این مورد حتی اگر پاسخ از نقطه پایانی حساب ها حاوی شناسه مشتری نباشد که با RP در approved_clients
مطابقت داشته باشد.
در این حالت ، disclosure_text_shown
ارسال شده به نقطه پایانی ادعای شناسه در بدنه HTTP نادرست است:
POST /id_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
account_id=123&client_id=client1234&nonce=234234&disclosure_text_shown=false
پیام خطا را نشان دهید
بعضی اوقات ، IDP ممکن است به دلایل قانونی نتواند نشانه ای از این نشانه را صادر کند ، مانند زمانی که مشتری غیرمجاز است ، یا سرور به طور موقت در دسترس نیست. اگر IDP پاسخ "خطا" را برگرداند ، RP می تواند آن را بدست آورد ، و Chrome می تواند با نشان دادن مرورگر 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 بر این اساس مفید است. همچنین ، هنگامی که در دسترس نباشد ، ممکن است از کاربر خواسته شود که با واسطه ای صریح کاربر وارد سیستم شود ، که این یک جریان با 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
> به طور خودکار وارد شوید. - در Android Chrome ، تنظیمات > مدیر رمز عبور > را باز کنید> روی یک COG در گوشه بالا سمت راست> ورود به سیستم خودکار ضربه بزنید.
با غیرفعال کردن ضامن ، کاربر می تواند از رفتار خودکار reeauthn همه با هم امتناع کند. اگر کاربر به یک حساب Google در نمونه Chrome امضا شود ، این تنظیم در دستگاه ها ذخیره و هماهنگ می شود.
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 بر روی مرورگر قطع می شوند و قول برطرف می شود. شناسه حسابهای قطع شده در پاسخ از نقطه پایانی قطع ارتباط مشخص شده است.