یک راه حل هویت با FedCM در سمت ارائه دهنده هویت پیاده سازی کنید

پیاده سازی FedCM شامل چندین مرحله اصلی برای هر دو Identity Provider (IdP) و Relying Party (RP) است. برای یادگیری نحوه پیاده سازی FedCM در سمت RP به مستندات مراجعه کنید.

IdP ها برای پیاده سازی FedCM باید مراحل زیر را انجام دهند:

یک فایل شناخته شده ایجاد کنید

برای جلوگیری از سوء استفاده ردیاب‌ها از 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 تعیین می شود. RP URL فایل پیکربندی را برای هر ارائه دهنده هویت ارسال می کند:

  // Executed on RP's side:
  try {
    const credential = await navigator.credentials.get({
      identity: {
        providers: [
          {
            // To allow users to sign in with the IdP1 using FedCM, RP specifies the IdP's config file URL:
            configUrl: 'https://idp1.example/foo.json', // first IdP
            clientId: '123',
          },
          // To allow users to sign in with the IdP2 using FedCM, RP specifies the IdP's config file URL.
          // Note that multiple IdPs in a single get() are supported from Chrome 136.
          {
            configUrl: 'https://idp2.example/bar.json', // second IdP
            clientId: '456',
          },
        ],
      },
    });

    const token = credential.token;
    // Get the current IdP's configURL to identify which provider the user is signed in with
    const currentIdpConfigUrl = credential.configURL;
    if (currentIdpConfigUrl === 'https://idp1.example/foo.json') {
      // handle the case where the user signed in with idp1
    } else if (currentIdpConfigUrl === 'https://idp2.example/bar.json') {
      // handle the case where the user signed in with idp2
    }
  } catch (error) {
    // handle error
  }

مرورگر فایل پیکربندی را با درخواست 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" بازگردانده می‌شوند.

توجه: برچسب‌های حساب سفارشی از Chrome 132 پشتیبانی می‌شوند.
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 (اختیاری) آرایه ای از اشیاء نماد. این نمادها در گفتگوی ورود به سیستم نمایش داده می شوند. شی نماد دارای دو پارامتر است:
  • url (الزامی): URL تصویر نماد. این از تصاویر SVG پشتیبانی نمی کند.
  • size (اختیاری): ابعاد آیکون، که توسط برنامه به صورت مربع و وضوح تک فرض شده است. این عدد باید بزرگتر یا مساوی 25 پیکسل در حالت غیرفعال و بزرگتر یا مساوی 40 پیکسل در حالت فعال باشد.
modes شیئی که حاوی مشخصات نحوه نمایش رابط کاربری FedCM در حالت های مختلف است:
  • active
  • passive
modes.active شیء حاوی ویژگی هایی که امکان سفارشی سازی رفتار FedCM را در یک حالت خاص فراهم می کند. هر دو modes.active و modes.passive می توانند شامل پارامتر زیر باشند:
  • supports_use_other_account : بولی که مشخص می‌کند آیا کاربر می‌تواند با حسابی متفاوت از حسابی که در حال حاضر با آن وارد شده است وارد شود (اگر IdP از چندین حساب پشتیبانی می‌کند).

توجه: از ویژگی سایر حساب‌ها استفاده کنید و حالت فعال از 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

از حساب دیگر استفاده کنید

اگر 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

پس از دریافت درخواست، سرور باید:

  1. بررسی کنید که درخواست حاوی سرصفحه HTTP Sec-Fetch-Dest: webidentity .
  2. کوکی‌های جلسه را با شناسه‌های حساب‌هایی که قبلاً وارد سیستم شده‌اند مطابقت دهید.
  3. با لیست حساب ها پاسخ دهید.

مرورگر انتظار پاسخ 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 می تواند برچسب گذاری حساب سفارشی را به صورت زیر پیاده سازی کند:
  • برچسب‌های حساب را در نقطه پایانی حساب‌ها مشخص کنید (با استفاده از این پارامتر labels ).
  • یک فایل پیکربندی برای هر برچسب خاص ایجاد کنید.

به عنوان مثال، یک IdP فایل پیکربندی https://idp.example/developer-config.json را با مشخص کردن "accounts": {"include": "developer"} پیاده سازی می کند. IdP همچنین برخی از حساب ها را با برچسب "developer" با استفاده از پارامتر labels در نقطه پایانی حساب ها علامت گذاری می کند. وقتی یک RP navigator.credentials.get() با فایل پیکربندی https://idp.example/developer-config.json فراخوانی می‌کند، فقط حساب‌هایی با برچسب "developer" بازگردانده می‌شوند.

برچسب‌های حساب سفارشی با راهنمای ورود و اشاره دامنه متفاوت هستند به گونه‌ای که به طور کامل توسط سرور IdP نگهداری می‌شوند و RP فقط فایل پیکربندی مورد استفاده را مشخص می‌کند.

توجه: برچسب‌های حساب سفارشی از Chrome 132 پشتیبانی می‌شوند.

نمونه بدن پاسخ:

  {
    "accounts": [{
      "id": "1234",
      "given_name": "John",
      "name": "John Doe",
      "email": "john_doe@idp.example",
      "picture": "https://idp.example/profile/123",
      // Ids of those RPs where this account can be used
      "approved_clients": ["123", "456", "789"],
      // This account has 'login_hints`. When an RP calls `navigator.credentials.get()`
      // with a `loginHint` value specified, for example, `exampleHint`, only those
      // accounts will be shown to the user whose 'login_hints' array contains the `exampleHint`.
      "login_hints": ["demo1", "exampleHint"],
      // This account is labelled. IdP can implement a specific config file for a
      // label, for example, `https://idp.example/developer-config.json`. Like that
      // RPs can filter out accounts by calling `navigator.credentials.get()` with
      // `https://idp.example/developer-config.json` config file.
      "labels": ["hr", "developer"]
    }, {
      "id": "5678",
      "given_name": "Johnny",
      "name": "Johnny",
      "email": "johnny@idp.example",
      "picture": "https://idp.example/profile/456",
      "approved_clients": ["abc", "def", "ghi"],
      "login_hints": ["demo2"],
      "domain_hints": ["@domain.example"]
    }]
  }

اگر کاربر وارد سیستم نشده است، با HTTP 401 (غیر مجاز) پاسخ دهید.

لیست حساب های برگشتی توسط مرورگر مصرف می شود و برای RP در دسترس نخواهد بود.

نقطه پایان ادعای شناسه

نقطه پایانی ادعای شناسه IdP یک ادعا را برای کاربر واردشده به سیستم باز می‌گرداند. هنگامی که کاربر با استفاده از فراخوان navigator.credentials.get() وارد یک وب سایت RP می شود، مرورگر یک درخواست POST با کوکی هایی با SameSite=None و یک نوع محتوا از application/x-www-form-urlencoded به این نقطه پایانی با اطلاعات زیر ارسال می کند:

اموال توضیحات
client_id (الزامی) شناسه مشتری RP.
account_id (الزامی) شناسه منحصر به فرد کاربر در حال ورود به سیستم.
disclosure_text_shown نتیجه در یک رشته "true" یا "false" (به جای یک بولی). نتیجه در این موارد "false" است:
  • اگر متن افشا نشان داده نمی‌شد زیرا شناسه مشتری RP در لیست ویژگی‌های approved_clients پاسخ از نقطه پایانی حساب‌ها گنجانده شده بود.
  • اگر متن افشا نشان داده نشد زیرا مرورگر یک لحظه ثبت نام را در گذشته در غیاب approved_clients مشاهده کرده است.
  • اگر پارامتر fields شامل یک یا چند فیلد از سه فیلد ("نام"، "ایمیل" و "تصویر") نباشد، برای مثال، fields=[ ] یا fields=['name', 'picture'] . این برای سازگاری با پیاده‌سازی‌های قدیمی‌تر IdP که انتظار دارند یک رشته افشا همیشه شامل هر سه فیلد باشد، لازم است.
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 معتبری که امکان تعیین پارامترهای کلیدی سفارشی اضافی را فراهم می کند، به عنوان مثال:
  • scope : یک مقدار رشته حاوی مجوزهای اضافی که RP باید درخواست کند، برای مثال "drive.readonly calendar.readonly"
  • nonce : یک رشته تصادفی ارائه شده توسط RP برای اطمینان از صدور پاسخ برای این درخواست خاص. از حملات تکراری جلوگیری می کند.
  • سایر پارامترهای کلیدی-مقدار سفارشی.
هنگامی که مرورگر یک درخواست POST ارسال می کند، مقدار 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&params=%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

پس از دریافت درخواست، سرور باید:

  1. با CORS (اشتراک گذاری منابع متقابل) به درخواست پاسخ دهید.
  2. بررسی کنید که درخواست حاوی سرصفحه HTTP Sec-Fetch-Dest: webidentity .
  3. سرصفحه Origin را با مبدا RP تعیین شده توسط client_id مطابقت دهید. اگر مطابقت نداشتند رد کنید.
  4. account_id با شناسه حسابی که قبلاً وارد سیستم شده‌اید مطابقت دهید. اگر مطابقت نداشتند رد کنید.
  5. با یک نشانه پاسخ دهید. اگر درخواست رد شد، با یک پاسخ خطا پاسخ دهید.

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 باید همان سایتی باشد که IdP configURL .
  // 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

پس از دریافت درخواست، سرور باید:

  1. با CORS (اشتراک گذاری منابع متقابل) به درخواست پاسخ دهید.
  2. بررسی کنید که درخواست حاوی سرصفحه HTTP Sec-Fetch-Dest: webidentity .
  3. سرصفحه Origin را با مبدا RP تعیین شده توسط client_id مطابقت دهید. اگر مطابقت نداشتند رد کنید.
  4. account_hint با شناسه‌های حساب‌هایی که قبلاً وارد سیستم شده‌اند مطابقت دهید.
  5. حساب کاربری را از RP جدا کنید.
  6. با اطلاعات حساب کاربری شناسایی شده در قالب 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

پس از دریافت درخواست، سرور باید:

  1. RP را برای client_id تعیین کنید.
  2. با فراداده مشتری پاسخ دهید.

ویژگی‌های نقطه پایانی فراداده مشتری عبارتند از:

اموال توضیحات
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 پیامی را نشان می دهد که ورود به سیستم را پیشنهاد می کند.

گفتگوی FedCM که پیشنهاد می کند به IdP وارد شوید.
گفتگوی FedCM که پیشنهاد می کند به IdP وارد شوید.

هنگامی که کاربر روی دکمه Continue کلیک می کند، مرورگر یک پنجره بازشو برای صفحه ورود IdP باز می کند.

یک مثال گفتگوی FedCM.
یک گفتگوی مثال پس از کلیک بر روی ورود به دکمه IdP نشان داده شده است.

گفتگو یک پنجره معمولی مرورگر است که کوکی های شخص اول دارد. هر آنچه در گفتگو اتفاق می افتد به IdP بستگی دارد و هیچ دسته پنجره ای برای درخواست ارتباط متقابل به صفحه RP در دسترس نیست. پس از ورود کاربر به سیستم، IdP باید:

  • هدر Set-Login: logged-in ارسال کنید یا با navigator.login.setStatus("logged-in") API تماس بگیرید تا به مرورگر اطلاع دهید که کاربر وارد سیستم شده است.
  • برای بستن دیالوگ، IdentityProvider.close() را فراخوانی کنید.
کاربر پس از ورود به IdP با استفاده از FedCM وارد RP می شود.

وضعیت ورود کاربر را به مرورگر اطلاع دهید

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 های خود پیاده سازی کنید و JavaScript SDK را توزیع کنید. با حذف نیاز به خود پیاده سازی، RP ها را به روز نگه دارید.
یاد بگیرید که چگونه محیط خود را راه اندازی کنید و پیاده سازی خود را اشکال زدایی کنید.
،

پیاده سازی FedCM شامل چندین مرحله اصلی برای هر دو Identity Provider (IdP) و Relying Party (RP) است. برای یادگیری نحوه پیاده سازی FedCM در سمت RP به مستندات مراجعه کنید.

IdP ها برای پیاده سازی FedCM باید مراحل زیر را انجام دهند:

یک فایل شناخته شده ایجاد کنید

برای جلوگیری از سوء استفاده ردیاب‌ها از 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 ها می توانند با مشخص کردن accounts_endpoint و login_url در پرونده مشهور ، چندین پرونده پیکربندی را برای یک IDP قرار دهند. این ویژگی در این موارد می تواند مفید باشد:

  • یک 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 تعیین می شود. RP URL پرونده پیکربندی را برای هر ارائه دهنده هویت منتقل می کند:

  // Executed on RP's side:
  try {
    const credential = await navigator.credentials.get({
      identity: {
        providers: [
          {
            // To allow users to sign in with the IdP1 using FedCM, RP specifies the IdP's config file URL:
            configUrl: 'https://idp1.example/foo.json', // first IdP
            clientId: '123',
          },
          // To allow users to sign in with the IdP2 using FedCM, RP specifies the IdP's config file URL.
          // Note that multiple IdPs in a single get() are supported from Chrome 136.
          {
            configUrl: 'https://idp2.example/bar.json', // second IdP
            clientId: '456',
          },
        ],
      },
    });

    const token = credential.token;
    // Get the current IdP's configURL to identify which provider the user is signed in with
    const currentIdpConfigUrl = credential.configURL;
    if (currentIdpConfigUrl === 'https://idp1.example/foo.json') {
      // handle the case where the user signed in with idp1
    } else if (currentIdpConfigUrl === 'https://idp2.example/bar.json') {
      // handle the case where the user signed in with idp2
    }
  } catch (error) {
    // handle error
  }

مرورگر فایل پیکربندی را با درخواست GET بدون هدر Origin یا Header 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" بازگردانده می شود.

توجه: برچسب های حساب سفارشی از Chrome 132 پشتیبانی می شوند.
client_metadata_endpoint (اختیاری) URL برای نقطه پایانی ابرداده مشتری .
id_assertion_endpoint (مورد نیاز) URL برای نقطه پایانی ادعای شناسه .
disconnect (اختیاری) URL برای نقطه پایانی قطع .
login_url (مورد نیاز) URL صفحه ورود به سیستم برای ورود کاربر به IDP.
branding (اختیاری) شیء که شامل گزینه های مختلف برندسازی است.
branding.background_color (اختیاری) گزینه برندسازی که رنگ پس زمینه دکمه "ادامه به عنوان ..." را تنظیم می کند. از نحو CSS مربوطه ، یعنی hex-color ، hsl() ، rgb() یا named-color استفاده کنید.
branding.color (اختیاری) گزینه برندسازی که رنگ متن دکمه "ادامه به عنوان ..." را تنظیم می کند. از نحو CSS مربوطه ، یعنی hex-color ، hsl() ، rgb() یا named-color استفاده کنید.
branding.icons (اختیاری) آرایه اشیاء نماد. این نمادها در گفتگوی ورود به سیستم نمایش داده می شوند. شیء نماد دارای دو پارامتر است:
  • url (مورد نیاز): URL تصویر نماد. این از تصاویر SVG پشتیبانی نمی کند.
  • size (اختیاری): ابعاد نماد ، فرض شده توسط برنامه وضوح مربعی و منفرد. این تعداد باید در حالت غیرفعال بیشتر یا برابر با 25px باشد و در حالت فعال بیشتر از یا مساوی با 40px باشد.
modes شیء که حاوی مشخصاتی در مورد نحوه نمایش FEDCM UI در حالت های مختلف است:
  • active
  • passive
modes.active اشیاء حاوی خواصی که امکان شخصی سازی رفتار FEDCM را در یک حالت خاص فراهم می کند. هر دو modes.active و modes.passive می توانند حاوی پارامتر زیر باشند:
  • supports_use_other_account : Boolean مشخص می کند که آیا کاربر می تواند با یک حساب متفاوت از شخصی که در حال حاضر با آن وارد شده است وارد سیستم شوید (اگر IDP از چندین حساب پشتیبانی کند).

توجه: از ویژگی های حساب دیگر استفاده کنید و حالت فعال از 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

از حساب دیگر استفاده کنید

اگر 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

پس از دریافت درخواست ، سرور باید:

  1. تأیید کنید که این درخواست حاوی یک Sec-Fetch-Dest: webidentity HTTP WebIDENTITY.
  2. کوکی های جلسه را با شناسه حساب های ثبت شده در حال حاضر مطابقت دهید.
  3. با لیست حساب ها پاسخ دهید.

مرورگر انتظار پاسخ 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() تماس بگیرد.
labels (اختیاری) مجموعه ای از برچسب های حساب سفارشی رشته ای که یک حساب با آن همراه است.
IDP می تواند برچسب زدن حساب سفارشی را به شرح زیر پیاده سازی کند:
  • برچسب های حساب را در نقطه پایانی حساب (با استفاده از این پارامتر labels ) مشخص کنید.
  • برای هر برچسب خاص یک فایل پیکربندی ایجاد کنید.

به عنوان مثال ، یک IDP https://idp.example/developer-config.json را با "accounts": {"include": "developer"} . IDP همچنین برخی از حساب ها را با برچسب "developer" با استفاده از پارامتر labels در نقطه پایانی حساب ها نشان می دهد. هنگامی که یک RP navigator.credentials.get() با https://idp.example/developer-config.json مشخص شده است ، فقط حساب هایی با برچسب "developer" بازگردانده می شود.

برچسب های حساب سفارشی با اشاره به ورود و اشاره به دامنه متفاوت است به گونه ای که آنها توسط سرور IDP کاملاً نگهداری می شوند و RP فقط پرونده پیکربندی را برای استفاده مشخص می کند.

توجه: برچسب های حساب سفارشی از Chrome 132 پشتیبانی می شوند.

مثال پاسخ بدن:

  {
    "accounts": [{
      "id": "1234",
      "given_name": "John",
      "name": "John Doe",
      "email": "john_doe@idp.example",
      "picture": "https://idp.example/profile/123",
      // Ids of those RPs where this account can be used
      "approved_clients": ["123", "456", "789"],
      // This account has 'login_hints`. When an RP calls `navigator.credentials.get()`
      // with a `loginHint` value specified, for example, `exampleHint`, only those
      // accounts will be shown to the user whose 'login_hints' array contains the `exampleHint`.
      "login_hints": ["demo1", "exampleHint"],
      // This account is labelled. IdP can implement a specific config file for a
      // label, for example, `https://idp.example/developer-config.json`. Like that
      // RPs can filter out accounts by calling `navigator.credentials.get()` with
      // `https://idp.example/developer-config.json` config file.
      "labels": ["hr", "developer"]
    }, {
      "id": "5678",
      "given_name": "Johnny",
      "name": "Johnny",
      "email": "johnny@idp.example",
      "picture": "https://idp.example/profile/456",
      "approved_clients": ["abc", "def", "ghi"],
      "login_hints": ["demo2"],
      "domain_hints": ["@domain.example"]
    }]
  }

اگر کاربر وارد سیستم نشده است ، با HTTP 401 (غیرمجاز) پاسخ دهید.

لیست حساب های برگشتی توسط مرورگر مصرف می شود و در دسترس RP نخواهد بود.

نقطه پایانی ادعای

نقطه پایانی ادعای شناسه IDP ادعایی را برای کاربر امضا شده خود بازگرداند. هنگامی که کاربر با استفاده از تماس با navigator.credentials.get() به وب سایت RP وارد می شود ، مرورگر درخواست POST را با کوکی ها با SameSite=None و یک نوع محتوا از application/x-www-form-urlencoded با اطلاعات زیر ارسال می کند:

اموال توضیحات
client_id (لازم) شناسه مشتری RP.
account_id (لازم) شناسه منحصر به فرد از امضا در کاربر.
disclosure_text_shown منجر به رشته ای از "true" یا "false" (به جای یک بولی) می شود. نتیجه در این موارد "false" است:
  • اگر متن افشای اطلاعات نشان داده نشده است زیرا شناسه مشتری RP در لیست املاک approved_clients پاسخ از پاسخ از نقطه پایانی حساب قرار گرفته است.
  • اگر متن افشای اطلاعات نشان داده نشده باشد زیرا مرورگر در صورت عدم وجود approved_clients ، لحظه ثبت نام را مشاهده کرده است.
  • اگر پارامتر fields شامل یک یا چند قسمت از سه قسمت ("نام" ، "ایمیل" و "تصویر") ، به عنوان مثال ، fields=[ ] ، یا fields=['name', 'picture'] نیست. این مورد برای سازگاری عقب مانده با پیاده سازی های قدیمی IDP که انتظار دارند یک رشته افشای اطلاعات همیشه شامل هر سه قسمت باشد ، لازم است.
is_auto_selected اگر تأیید خودکار بر روی RP انجام شود ، is_auto_selected "true" را نشان می دهد. در غیر این صورت "false" . این برای پشتیبانی از ویژگی های بیشتر مربوط به امنیت مفید است. به عنوان مثال ، برخی از کاربران ممکن است یک ردیف امنیتی بالاتر را ترجیح دهند که به واسطه صریح کاربر در تأیید اعتبار نیاز داشته باشد. اگر یک IDP بدون چنین واسطه ای درخواست توکن را دریافت کند ، می تواند درخواست را متفاوت انجام دهد. به عنوان مثال ، یک کد خطا را به گونه ای برگردانید که RP بتواند دوباره با API FEDCM با mediation: required .
fields (اختیاری) مجموعه ای از رشته هایی که اطلاعات کاربر را مشخص می کند ("نام" ، "ایمیل" ، "تصویر") که RP برای به اشتراک گذاشتن با آنها به IDP نیاز دارد.
مرورگر fields ، disclosure_text_shown و disclosure_shown_for را ارسال می کند و لیست های مشخص شده را در درخواست پست ، مانند مثال زیر لیست می کند.

توجه: پارامتر Fields از Chrome 132 پشتیبانی می شود.
params (اختیاری) هر شیء معتبر JSON که امکان می دهد پارامترهای اضافی با ارزش کلید سفارشی اضافی را مشخص کند ، به عنوان مثال:
  • scope : مقدار رشته ای حاوی مجوزهای اضافی که RP باید درخواست کند ، به عنوان مثال "drive.readonly calendar.readonly"
  • nonce : یک رشته تصادفی ارائه شده توسط RP برای اطمینان از پاسخ برای این درخواست خاص. از حملات پخش مجدد جلوگیری می کند.
  • سایر پارامترهای ارزش کلید سفارشی.
هنگامی که مرورگر یک درخواست پست ارسال می کند ، مقدار params به JSON سریال می شود و سپس درصد رمزگذاری می شود .

توجه: پارامترهای API توسط Chrome 132 و بعد از آن پشتیبانی می شود.

مثال هدر HTTP:

  POST /assertion.example HTTP/1.1
  Host: accounts.idp.example
  Origin: https://rp.example/
  Content-Type: application/x-www-form-urlencoded
  Cookie: 0x23223
  Sec-Fetch-Dest: webidentity

  // disclosure_text_shown is set to 'false', as the 'name' field value is missing in 'fields' array
  // params value is serialized to JSON and then percent-encoded.
  account_id=123&client_id=client1234&disclosure_text_shown=false&is_auto_selected=true&params=%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

پس از دریافت درخواست ، سرور باید:

  1. به درخواست با CORS پاسخ دهید (به اشتراک گذاری منابع متقاطع) .
  2. تأیید کنید که این درخواست حاوی یک Sec-Fetch-Dest: webidentity HTTP WebIDENTITY.
  3. هدر Origin را در مقابل مبدا RP که توسط client_id تعیین شده است مطابقت دهید. اگر آنها مطابقت نداشته باشند ، رد کنید.
  4. account_id در برابر شناسه حساب از قبل امضا شده مطابقت دهید. اگر آنها مطابقت نداشته باشند ، رد کنید.
  5. با یک نشانه پاسخ دهید. اگر درخواست رد شد ، با پاسخ خطا پاسخ دهید.

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 نیاز به درخواست اطلاعات اضافی یا مجوزها دارد ، به عنوان مثال:

  • اجازه دسترسی به منابع سمت سرور کاربر.
  • تأیید اینکه اطلاعات تماس به روز است.
  • کنترل های والدین

نقطه پایانی ادعای شناسه می تواند یک ویژگی continue_on داشته باشد که شامل یک مسیر مطلق یا نسبی به نقطه پایانی ادعای شناسه است.

  {
    // In the id_assertion_endpoint, instead of returning a typical
    // "token" response, the IdP decides that it needs the user to
    // continue on a popup window:
    "continue_on": "https://idp.example/continue_on_url"
  }

اگر پاسخ حاوی پارامتر continue_on باشد ، یک پنجره پنجره جدید باز می شود و کاربر را به مسیر مشخص شده منتقل می کند. پس از تعامل کاربر با صفحه continue_on ، IDP باید با IdentityProvider.resolve() با نشانه ای که به عنوان یک آرگومان تصویب شده است ، تماس بگیرد تا وعده از navigator.credentials.get() تماس قابل حل باشد:

  document.getElementById('example-button').addEventListener('click', async () => {
    let accessToken = await fetch('/generate_access_token.cgi');
    // Closes the window and resolves the promise (that is still hanging
    // in the relying party's renderer) with the value that is passed.
    IdentityProvider.resolve(accessToken);
  });

مرورگر سپس به طور خودکار پنجره را می بندد و نشانه را به تماس گیرنده API باز می گرداند. یک تماس یک بار IdentityProvider.resolve() تنها راه برای برقراری ارتباط با پنجره والدین (RP) و پنجره بازشو (IDP) است.
اگر کاربر درخواست را رد کند ، IDP می تواند پنجره را با تماس با IdentityProvider.close() ببندد.

  IdentityProvider.close();

API ادامه کار به تعامل صریح کاربر (کلیک) نیاز دارد. در اینجا نحوه عملکرد API ادامه با حالت های واسطه ای مختلف آورده شده است:

  • در حالت منفعل :
    • mediation: 'optional' (پیش فرض): API ادامه فقط با یک ژست کاربر کار خواهد کرد ، مانند کلیک بر روی یک دکمه در صفحه یا روی UI FEDCM. هنگامی که مجدداً خودکار بدون حرکات کاربر ایجاد می شود ، هیچ پنجره پنجره ای باز نمی شود و قول رد می شود.
    • mediation: 'required' : همیشه از کاربر می خواهد که تعامل داشته باشد ، بنابراین API ادامه همیشه کار می کند.
  • در حالت فعال :
    • فعال سازی کاربر همیشه مورد نیاز است. 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 با یک پیام خطای عمومی UI خطا را ارائه می دهد و کد را به RP منتقل می کند.
  • url : این یک صفحه وب قابل خواندن با انسانی را با اطلاعات مربوط به خطا برای ارائه اطلاعات بیشتر در مورد خطا برای کاربران مشخص می کند. این زمینه برای کاربران مفید است زیرا مرورگرها نمی توانند پیام های خطای غنی را در یک UI داخلی ارائه دهند. به عنوان مثال: پیوندها برای مراحل بعدی یا اطلاعات تماس با خدمات مشتری. اگر کاربر بخواهد در مورد جزئیات خطا و نحوه رفع آن اطلاعات بیشتری کسب کند ، می تواند برای اطلاعات بیشتر به صفحه ارائه شده از UI مرورگر مراجعه کند. URL باید از همان سایت با configURL IDP باشد.
  // id_assertion_endpoint response
  {
    "error" : {
      "code": "access_denied",
      "url" : "https://idp.example/error?type=access_denied"
    }
  }

برچسب های حساب سفارشی

با برچسب های حساب سفارشی ، IDP می تواند حساب های کاربری را با برچسب ها حاشیه نویسی کند ، و RP می تواند با مشخص کردن configURL برای آن برچسب خاص ، فقط حساب های خود را با برچسب های خاص انتخاب کند. این می تواند مفید باشد که یک RP نیاز به فیلتر کردن حساب ها با معیارهای خاص ، به عنوان مثال ، فقط نمایش حساب های خاص مانند "developer" یا "hr" را نشان دهد.

فیلتر مشابه با استفاده از Domain Hint و ویژگی های ورود به سیستم ، با مشخص کردن آنها در تماس navigator.credentials.get() امکان پذیر است. با این حال ، برچسب های حساب سفارشی می توانند با مشخص کردن پرونده پیکربندی ، کاربران را فیلتر کنند ، که به ویژه در هنگام استفاده از چندین پیکربندی مفید است. برچسب های حساب سفارشی نیز از نظر ارائه شده از سرور IDP ، بر خلاف RP ، مانند نشانه های ورود یا دامنه ، متفاوت هستند.

یک IDP را در نظر بگیرید که می خواهد بین حساب های "developer" و "hr" تمایز قائل شود. برای دستیابی به این هدف ، IDP به ترتیب باید از دو پیکربندی برای "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 باشد تا چندین پیکربندی امکان پذیر باشد:
  {
    "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" اجازه ورود به سیستم را بدهد ، می توانند پیکربندی 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

پس از دریافت درخواست ، سرور باید:

  1. به درخواست با CORS پاسخ دهید (به اشتراک گذاری منابع متقاطع) .
  2. تأیید کنید که این درخواست حاوی یک Sec-Fetch-Dest: webidentity HTTP WebIDENTITY.
  3. هدر Origin را در مقابل مبدا RP که توسط client_id تعیین شده است مطابقت دهید. اگر آنها مطابقت نداشته باشند ، رد کنید.
  4. account_hint با IDS حساب های ثبت شده در حال حاضر.
  5. حساب کاربری را از RP جدا کنید.
  6. با اطلاعات حساب کاربری شناسایی شده با فرمت JSON به مرورگر پاسخ دهید.

یک پاسخ به عنوان مثال JSON Payload به این شکل است:

  {
    "account_id": "account456"
  }

در عوض ، اگر IDP آرزو می کند که مرورگر تمام حساب های مرتبط با RP را جدا کند ، رشته ای را منتقل کنید که با هیچ شناسه حساب مطابقت ندارد ، به عنوان مثال "*" .

نقطه پایانی ابرداده مشتری

نقطه پایانی ابرداده مشتری IDP ابرداده متکی به حزب مانند خط مشی رازداری RP ، شرایط خدمات و نمادهای آرم را برمی گرداند. RPS باید از قبل پیوندهایی به خط مشی رازداری و شرایط خدمات خود به IDP ارائه دهد. این پیوندها وقتی کاربر هنوز در RP با IDP ثبت نام نکرده است ، در گفتگوی ورود به سیستم نمایش داده می شود.

مرورگر با استفاده از client_id navigator.credentials.get بدون کوکی درخواست 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

پس از دریافت درخواست ، سرور باید:

  1. RP را برای client_id تعیین کنید.
  2. با ابرداده مشتری پاسخ دهید.

خصوصیات نقطه پایانی ابرداده مشتری شامل موارد زیر است:

اموال توضیحات
privacy_policy_url (اختیاری) URL سیاست حفظ حریم خصوصی RP.
terms_of_service_url (اختیاری) شرایط RP URL خدمات.
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 استفاده می شود.

با استفاده از API وضعیت ورود به سیستم ، IDP باید وضعیت ورود کاربر را به مرورگر اطلاع دهد. با این حال ، وضعیت می تواند از همگام سازی خارج شود ، مانند زمان منقضی شدن جلسه . در چنین سناریویی ، مرورگر می تواند به صورت پویا به کاربر اجازه دهد از طریق URL صفحه ورود به سیستم ورود به سیستم IDP Config File login_url وارد IDP شود.

گفتگوی FEDCM پیامی را نشان می دهد که یک علامت را نشان می دهد ، همانطور که در تصویر زیر نشان داده شده است.

گفتگوی FEDCM که پیشنهاد می کند وارد IDP شود.
گفتگوی FEDCM که پیشنهاد می کند وارد IDP شود.

هنگامی که کاربر روی دکمه ادامه کلیک می کند ، مرورگر یک پنجره بازشو را برای صفحه ورود به سیستم IDP باز می کند.

مثالی گفتگوی FEDCM.
یک گفتگوی مثال که پس از کلیک بر روی علامت وارد شده به دکمه IDP نشان داده شده است.

این گفتگو یک پنجره مرورگر معمولی است که کوکی های شخص اول دارد. هر اتفاقی که در گفتگو رخ می دهد به IDP بستگی دارد و هیچ دسته پنجره ای برای ایجاد یک درخواست ارتباطی متقاطع به صفحه RP در دسترس نیست. پس از ورود کاربر ، IDP باید:

  • برای اطلاع از مرورگر که کاربر وارد سیستم شده است ، API را ارسال کنید Set-Login: logged-in یا با navigator.login.setStatus("logged-in") تماس بگیرید.
  • برای بستن گفتگو IdentityProvider.close() تماس بگیرید.
یک کاربر پس از ورود به IDP با استفاده از FEDCM وارد RP می شود.

در مورد وضعیت ورود به سیستم کاربر به مرورگر اطلاع دهید

API وضعیت ورود به سیستم مکانیسمی است که یک وب سایت ، به ویژه یک IDP ، وضعیت ورود کاربر را در IDP به مرورگر اطلاع می دهد. با استفاده از این API ، مرورگر می تواند درخواست های غیر ضروری را به IDP کاهش داده و حملات زمان بندی بالقوه را کاهش دهد .

IDP ها می توانند با ارسال یک هدر HTTP یا با تماس با API JavaScript هنگام ورود کاربر در IDP یا هنگام ورود کاربر از تمام حساب های IDP ، وضعیت ورود کاربر را به مرورگر نشان دهند. برای هر IDP (که توسط URL پیکربندی آن مشخص شده است) مرورگر یک متغیر سه حالت را نشان می دهد که حالت ورود به سیستم را با مقادیر ممکن نشان می دهد:

  • logged-in
  • logged-out
  • unknown (پیش فرض)
حالت ورود به سیستم توضیحات
logged-in هنگامی که وضعیت ورود کاربر روی logged-in تنظیم شده است ، RP Calling FedCM درخواست هایی را به نقطه پایانی حساب های IDP می دهد و حساب های موجود را در گفتگوی FEDCM به کاربر نشان می دهد.
logged-out هنگامی که وضعیت ورود به سیستم کاربر logged-out است ، تماس با FEDCM بی سکوت بدون درخواست به نقطه پایانی حساب های IDP انجام می شود.
unknown (پیش فرض) وضعیت unknown قبل از ارسال IDP سیگنال با استفاده از API وضعیت ورود به سیستم تنظیم شده است. هنگامی که وضعیت unknown است ، مرورگر درخواست انتهای حساب های IDP می کند و وضعیت را بر اساس پاسخ از نقطه پایانی حساب ها به روز می کند.

برای اینکه سیگنال شود که کاربر وارد سیستم شده است ، یک Set-Login: logged-in HTTP ورود به سیستم در یک ناوبری سطح بالا یا یک درخواست زیر منبع مشابه در منشأ IDP:

  Set-Login: logged-in

از طرف دیگر ، با روش javascript navigator.login.setStatus('logged-in') از مبدا IDP در یک ناوبری سطح بالا تماس بگیرید:

  navigator.login.setStatus('logged-in')

وضعیت ورود به سیستم کاربر به صورت logged-in تنظیم می شود.

برای نشان دادن اینکه کاربر از تمام حسابهای خود امضا شده است ، یک Set-Login: logged-out در یک ناوبری سطح بالا یا یک درخواست فرعی یک سایت در منشأ IDP:

  Set-Login: logged-out

از طرف دیگر ، با JavaScript API navigator.login.setStatus('logged-out') از مبدا IDP در یک ناوبری سطح بالا تماس بگیرید:

  navigator.login.setStatus('logged-out')

وضعیت ورود به سیستم کاربر به صورت logged-out تنظیم می شود.

وضعیت unknown قبل از ارسال IDP سیگنال با استفاده از API وضعیت ورود به سیستم تنظیم شده است. مرورگر درخواستی را به نقطه پایانی حساب های IDP ارائه می دهد و وضعیت را بر اساس پاسخ از نقطه پایانی حساب ها به روز می کند:

  • اگر نقطه پایانی لیستی از حسابهای فعال را بازگرداند ، وضعیت را برای logged-in روز کنید و گفتگوی FEDCM را باز کنید تا آن حساب ها را نشان دهید.
  • اگر نقطه پایانی هیچ حساب را برنگردد ، وضعیت را برای logged-out روز کنید و تماس FEDCM را شکست دهید.

بگذارید کاربر از طریق یک جریان ورود به سیستم پویا وارد سیستم شود

حتی اگر IDP وضعیت ورود به سیستم کاربر را به مرورگر اطلاع می دهد ، می تواند از همگام سازی خارج شود ، مانند زمان منقضی شدن جلسه. مرورگر سعی می کند هنگام logged-in سیستم ، یک درخواست معتبر را به نقطه پایانی حساب ارسال کند ، اما سرور هیچ حساب نمی کند زیرا جلسه دیگر در دسترس نیست. در چنین سناریویی ، مرورگر می تواند به صورت پویا اجازه دهد کاربر از طریق پنجره بازشو وارد IDP شود .

مراحل بعدی

FedCM را برای RP های خود پیاده سازی کنید و JavaScript SDK را توزیع کنید. با حذف نیاز به خود پیاده سازی، RP ها را به روز نگه دارید.
یاد بگیرید که چگونه محیط خود را راه اندازی کنید و پیاده سازی خود را اشکال زدایی کنید.