تنفيذ حلّ للتحقّق من الهوية باستخدام FedCM

FedCM (إدارة بيانات الاعتماد الموحّدة) هي نهج للحفاظ على الخصوصية في خدمات إدارة الهوية الموحّدة (مثل "تسجيل الدخول باستخدام...") التي تتيح للمستخدمين تسجيل الدخول إلى المواقع الإلكترونية بدون مشاركة معلوماتهم الشخصية مع خدمة إدارة الهوية أو الموقع الإلكتروني.

يتضمّن تنفيذ FedCM عدة خطوات أساسية لكل من موفِّر الهوية (IdP) والطرف الموثوق به (RP).

على IdPs إكمال الخطوات التالية لتنفيذ FedCM:

على المورّدين إكمال الخطوات التالية لتفعيل FedCM على موقعهم الإلكتروني:

تنفيذ FedCM كموفِّر هوية

اطّلِع على مزيد من المعلومات عن خطوات تنفيذ FedCM من جهة موفِّر الهوية.

إنشاء ملف well-known

لمنع أجهزة التتبُّع من إساءة استخدام واجهة برمجة التطبيقات (API)، يجب عرض ملف well-known من /.well-known/web-identity في النطاق العلوي للمستوى التالي (eTLD+1) لموفِّر الهوية (IdP).

يمكن أن يتضمّن الملف المعروف السمات التالية:

الموقع مطلوب الوصف
provider_urls مطلوب صفيف لمسارات ملفات إعداد موفِّر الهوية يتم تجاهلها (ولكنها لا تزال مطلوبة) في حال تحديد accounts_endpoint وlogin_url.
accounts_endpoint يُنصح باستخدامها، وتتطلّب login_url
عنوان URL لنقطة نهاية الحسابات يتيح ذلك إمكانية استخدام إعدادات متعددة، ما دام كل ملف إعداد يستخدم عنوانَي URL login_url وaccounts_endpoint نفسيهما.

ملاحظة: تتوفّر المَعلمة اعتبارًا من الإصدار 132 من Chrome.
login_url يُنصح به، ويتطلب accounts_endpoint عنوان URL لصفحة تسجيل الدخول للمستخدم لتسجيل الدخول إلى موفِّر الهوية يتيح ذلك إمكانية استخدام إعدادات متعددة، ما دام كل ملف إعداد يستخدم login_url وaccounts_endpoint نفسهما.

ملاحظة: تتوفّر المَعلمة اعتبارًا من الإصدار 132 من Chrome والإصدارات الأحدث.

على سبيل المثال، إذا كانت نقاط نهاية موفِّر الهوية معروضة ضمن https://accounts.idp.example/، يجب أن تعرض ملفًا معروفًا في https://idp.example/.well-known/web-identity بالإضافة إلى ملف إعدادات موفِّر هوية. في ما يلي مثال على محتوى ملف معروف:

  {
    "provider_urls": ["https://accounts.idp.example/config.json"]
  }

يمكن لموفّري الهوية استيعاب ملفات إعدادات متعددة لموفّر الهوية، وذلك من خلال تحديد accounts_endpoint وlogin_url في ملف well-known.
يمكن أن تكون هذه الميزة مفيدة في الحالات التالية:

  • يجب أن يتيح موفِّر خدمة إدارة الهوية إعدادات متعددة مختلفة للاختبار والإصدار العلني.
  • يجب أن يتيح موفِّر الهوية إعدادات مختلفة لكل منطقة (على سبيل المثال، eu-idp.example وus-idp.example).

لتتوافق مع الإعدادات المتعددة (على سبيل المثال، للتمييز بين بيئة الاختبار وبيئة الإنتاج)، يجب أن يحدِّد موفِّر خدمة إدارة الهوية 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"
  }

إنشاء ملف إعدادات موفِّر الهوية ونقاط النهاية

يقدّم ملف إعدادات موفِّر الهوية قائمة بنقاط النهاية المطلوبة للمتصفح. يجب أن تستضيف موفّري الهوية ملفًا واحدًا أو عدة ملفات إعدادات ونقاط النهاية وعناوين URL المطلوبة. يجب عرض جميع application/json JSON الاستجابات باستخدام نوع المحتوى application/json.

يتم تحديد عنوان URL لملف الإعدادات من خلال القيم المقدَّمة لاستدعاء navigator.credentials.get() الذي يتم تنفيذه على جهاز RP.

  const credential = await navigator.credentials.get({
    identity: {
      context: 'signup',
      providers: [{
        configURL: 'https://accounts.idp.example/config.json',
        clientId: '********',
        nonce: '******'
      }]
    }
  });
  const { token } = credential;

سيُرسِل مقدّم الخدمة عنوان URL لملف الإعداد إلى طلب FedCM API للسماح للمستخدم بتسجيل الدخول:

  // Executed on RP's side:
  const credential = await navigator.credentials.get({
    identity: {
      context: 'signup',
      providers: [{
        // To allow users to sign in with an IdP using FedCM, RP specifies the IdP's config file URL:
        configURL: 'https://accounts.idp.example/fedcm.json',
        clientId: '********',
  });
  const { token } = credential;

سيجلب المتصفّح ملف الإعدادات باستخدام طلب GET بدون عنوان Origin أو عنوان Referer. لا يتضمّن الطلب ملفات تعريف الارتباط ولا يتّبع عمليات إعادة التوجيه. ويؤدي ذلك إلى منع موفِّر الهوية بشكل فعّال من معرفة الجهة التي قدّمت الطلب ومحاولة العميل المرتبط بالحساب الربط. على سبيل المثال:

  GET /config.json HTTP/1.1
  Host: accounts.idp.example
  Accept: application/json
  Sec-Fetch-Dest: webidentity

يجب أن ينفِّذ موفِّر الهوية نقطة نهاية للإعداد تستجيب بتنسيق JSON. يتضمّن ملف JSON السمات التالية:

الموقع الوصف
accounts_endpoint (مطلوب) عنوان URL لنقطة نهاية الحسابات
accounts.include (اختياري) سلسلة تصنيف الحساب المخصّصة التي تحدّد الحسابات التي يجب عرضها عند استخدام ملف الإعدادات هذا، على سبيل المثال: "accounts": {"include": "developer"}.
يمكن لموفِّر الهوية (IdP) تنفيذ تصنيف الحسابات المخصّص على النحو التالي:

على سبيل المثال، ينفِّذ موفِّر الهوية "https://idp.example/developer-config.json" ملف الإعداد مع تحديد "accounts": {"include": "developer"}. يضع موفِّر الهوية أيضًا تصنيف "developer" على بعض الحسابات باستخدام المَعلمة labels في نقطة نهاية الحسابات. عندما يتصل مقدّم المحتوى بـ navigator.credentials.get() مع تحديد ملف الإعداد "https://idp.example/developer-config.json"، لن يتم عرض سوى الحسابات التي تحمل التصنيف "developer".
client_metadata_endpoint (اختياري) عنوان URL لنقطة نهاية البيانات الوصفية للعميل
id_assertion_endpoint (مطلوب) عنوان URL لنقطة نهاية بيان الهوية.
disconnect (اختياري) عنوان URL لنقطة نهاية إلغاء الاتصال
login_url (مطلوب) عنوان URL لصفحة تسجيل الدخول للمستخدم لتسجيل الدخول إلى موفِّر الهوية
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: قيمة منطقية تحدّد ما إذا كان بإمكان المستخدم تسجيل الدخول باستخدام حساب مختلف عن الحساب الذي سجّل الدخول إليه حاليًا (إذا كان موفِّر خدمة المصادقة يتوافق مع حسابات متعددة).

ملاحظة: تتوفّر ميزة "استخدام حساب آخر" والوضع النشط من الإصدار 132 من Chrome.
modes.passive

في ما يلي مثال على نص الاستجابة من موفّر الهوية:

  {
    "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
      }]
    }
  }

بعد أن يجلب المتصفّح ملف الإعدادات، يرسل طلبات لاحقة إلى نقاط نهاية IDEP:

نقاط نهاية موفِّر الهوية
نقاط نهاية موفِّر الهوية (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
    }
  }

نقطة نهاية الحسابات

تعرض نقطة نهاية حسابات موفِّر الهوية قائمة بالحسابات التي سجّل المستخدم الدخول إليها على موفِّر الهوية. إذا كان موفِّر خدمة المصادقة يتيح استخدام حسابات متعددة، ستُرجع هذه نقطة النهاية جميع الحسابات التي تم تسجيل الدخول إليها.

يُرسِل المتصفّح طلبًا من النوع GET يتضمّن ملفات تعريف ارتباط تتضمّن SameSite=None، ولكن بدون مَعلمة client_id أو عنوان Origin أو عنوان Referer. ويؤدي ذلك بفعال إلى منع موفِّر الهوية من معرفة موفِّر الخدمات الذي يحاول المستخدم تسجيل الدخول إليه. على سبيل المثال:

  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 (اختياري) مصفوفة من جميع أنواع الفلاتر الممكنة التي يتيحها موفِّر الهوية لتحديد حساب يمكن لـ RP استدعاء navigator.credentials.get() باستخدام الموقع loginHint لإظهار الحساب المحدّد بشكل انتقائي.
domain_hints (اختياري) صفيف يضمّ جميع النطاقات المرتبطة بالحساب يمكن لـ RP الاتصال بـ navigator.credentials.get() باستخدام موقع domainHint لفلترة الحسابات.
labels (اختياري) صفيف من تصنيفات الحساب المخصّصة التي يرتبط بها حساب معيّن
يمكن لموفِّر الهوية (IdP) تنفيذ تصنيف الحسابات المخصّص على النحو التالي:
  • حدِّد تصنيفات الحسابات في نقطة نهاية الحسابات (باستخدام مَعلمة labels هذه).
  • أنشئ ملف إعدادات لكل تصنيف محدّد.

على سبيل المثال، ينفِّذ موفِّر الهوية https://idp.example/developer-config.json ملف الإعداد مع تحديد "accounts": {"include": "developer"}. يضع موفِّر الهوية أيضًا تصنيف "developer" على بعض الحسابات باستخدام المَعلمة labels في نقطة نهاية حسابات. عندما يتصل مقدّم المحتوى بـ navigator.credentials.get() مع تحديد ملف الإعداد https://idp.example/developer-config.json، لن يتم عرض سوى الحسابات التي تحمل التصنيف "developer".

تختلف تصنيفات الحسابات المخصّصة عن تلميحات تسجيل الدخول وتلميحات النطاقات على نحو يحافظ فيه خادم موفّر الهوية على هذه التصنيفات بالكامل، ولا يحدّد موفّر الاعتماد سوى ملف الإعدادات المراد استخدامه.

مثال على نص الاستجابة:

  {
    "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 (غير مصرّح به).

يستخدم المتصفّح قائمة الحسابات التي تم عرضها ولن تكون متاحة لمسؤول المراجعة.

نقطة نهاية بيان الهوية

تعرض نقطة نهاية بيان الهوية لموفِّر الهوية بيانًا للمستخدم الذي سجّل الدخول. عندما يسجّل المستخدم الدخول إلى موقع إلكتروني تابع لخدمة مقارنة الأسعار باستخدام طلب navigator.credentials.get()، يُرسِل المتصفّح طلب POST يتضمّن ملفات تعريف ارتباط SameSite=None ونوع محتوى application/x-www-form-urlencoded إلى هذه نقطة النهاية مع المعلومات التالية:

الموقع الوصف
client_id (مطلوب) معرّف العميل لمسؤول المعالجة
account_id (مطلوب) المعرّف الفريد للمستخدِم الذي سجّل الدخول.
disclosure_text_shown تؤدي إلى ظهور سلسلة من "true" أو "false" (بدلاً من قيمة منطقية). تكون النتيجة "false" في الحالات التالية:
  • إذا لم يتم عرض نص الإفصاح لأنّه تم تضمين رقم تعريف العميل الخاص بمسؤول المعالجة في قائمة approved_clients للردّ من نقطة نهاية الحسابات.
  • إذا لم يتم عرض نص بيان الإفصاح لأنّ المتصفّح رصد لحظة اشتراك في الماضي في غياب approved_clients.
  • إذا كانت المَعلمة fields لا تتضمّن حقلًا واحدًا أو أكثر من الحقول الثلاثة ("الاسم" و"البريد الإلكتروني" و "الصورة")، على سبيل المثال، fields=[ ] أو fields=['name', 'picture']. ويُعدّ ذلك ضروريًا للتوافق مع الإصدارات القديمة من عمليات تنفيذ موفِّري خدمات التعريف التي تتوقّع أن تتضمّن سلسلة بيان الإفصاح دائمًا جميع الحقول الثلاثة.
is_auto_selected في حال تنفيذ إعادة المصادقة التلقائية على نقطة الربط، يشير is_auto_selected إلى "true". بخلاف ذلك، "false". ويساعد ذلك في توفير المزيد من الميزات المتعلّقة بالأمان. على سبيل المثال، قد يفضّل بعض المستخدمين مستوى أمان أعلى يتطلّب توسّط المستخدم بشكل صريح في المصادقة. إذا تلقّى موفّر الهوية طلب رمز مميّز بدون هذا التوسّط، يمكنه معالجة الطلب بشكل مختلف. على سبيل المثال، يمكنك عرض رمز خطأ ليتمكّن موفِّر المحتوى من طلب البيانات من واجهة برمجة التطبيقات FedCM مرة أخرى باستخدام mediation: required.
fields (اختياري) صفيف من السلاسل التي تحدّد معلومات المستخدم ("الاسم" و"البريد الإلكتروني" و"الصورة") التي يحتاج إليها مقدّم طلب الاعتماد من موفّر الهوية لمشاركتها معه.
سيرسل المتصفّح fields وdisclosure_text_shown وdisclosure_shown_for مع إدراج الحقول المحدّدة في طلب POST، كما هو موضّح في المثال التالي.

ملاحظة: تتوفّر المَعلمة Fields اعتبارًا من الإصدار 132 من Chrome.
params (اختياري) أيّ كائن JSON صالح يسمح بتحديد مَعلمات مفتاح/قيمة مخصّصة إضافية، على سبيل المثال:
  • scope: قيمة سلسلة تحتوي على أذونات إضافية يحتاجها مقدّم الطلب، على سبيل المثال "drive.readonly calendar.readonly"
  • nonce: سلسلة عشوائية يوفّرها مقدّم الخدمة لضمان إصدار الردّ لهذا الطلب المحدّد. منع هجمات إعادة التشغيل
  • مَعلمات مخصّصة أخرى للقيم/المفاتيح
عندما يُرسِل المتصفّح طلب POST، سيتم تسلسل قيمة params إلى تنسيق JSON ثم ترميزها باستخدام النسبة المئوية.

ملاحظة: تتوفّر واجهة برمجة التطبيقات Parameters API في الإصدار 132 من Chrome والإصدارات الأحدث.

مثال على عنوان 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. يجب الردّ باستخدام رمز مميّز. في حال رفض الطلب، يجب الردّ باستخدام استجابة خطأ.

يمكن لموفّر خدمة المصادقة تحديد كيفية إصدار الرمز المميّز. بشكل عام، يتم التوقيع عليه باستخدام معلومات مثل رقم تعريف الحساب ورقم تعريف العميل ومصدر جهة الإصدار وعدد الطلبات العشوائي، كي تتمكّن وحدة التحكّم في الوصول من التأكّد من أنّ الرمز المميّز أصلي.

يتوقّع المتصفّح استجابة JSON تتضمّن السمة التالية:

الموقع الوصف
token رمز المرور هو سلسلة تحتوي على إثباتات حول المصادقة.
continue_on عنوان URL لإعادة التوجيه الذي يتيح عملية تسجيل دخول متعددة الخطوات

يُرسِل المتصفّح الرمز المميّز الذي تم إرجاعه إلى مقدّم الخدمة لكي يتمكّن من إثبات صحة المصادقة.

  {
    // IdP can respond with a token to authenticate the user
    "token": "***********"
  }
ميزة "المتابعة على"

يمكن لموفِّر الهوية (IdP) تقديم عنوان URL لإعادة التوجيه في استجابة نقطة نهاية بيان الهوية لتفعيل مسار تسجيل دخول يتضمّن خطوات متعددة. يكون ذلك مفيدًا عندما يحتاج موفِّر خدمة إدارة الهوية إلى طلب معلومات أو أذونات إضافية، على سبيل المثال:

  • إذن الوصول إلى موارد المستخدم من جهة الخادم
  • إثبات أنّ معلومات الاتصال محدّثة
  • أدوات رقابة الأهل

يمكن أن تعرِض نقطة نهاية بيان الهوية عنصرًا من النوع 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، يجب أن يتصل موفِّر الهوية 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);
  });

بعد ذلك، سيغلق المتصفّح النافذة المنبثقة تلقائيًا ويُعيد الرمز المميّز إلى المُرسِل الذي يطلب بيانات من واجهة برمجة التطبيقات. إنّ الاتصال برقم IdentityProvider.resolve() لمرة واحدة هو الطريقة الوحيدة للتواصل بين النافذة الرئيسية (RP) والنافذة المنبثقة (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: يمكن لموفِّر الهوية اختيار أحد الأخطاء المعروفة من قائمة أخطاء OAuth 2.0 المحدّدة (invalid_request وunauthorized_client وaccess_denied وserver_error و temporarily_unavailable) أو استخدام أي سلسلة عشوائية. في هذه الحالة، يعرض Chrome واجهة مستخدم الخطأ مع رسالة خطأ عامة ويرسل الرمز إلى موفِّر المحتوى.
  • url: يحدِّد هذا الحقل صفحة ويب قابلة للقراءة من قِبل المستخدمين تتضمّن معلومات عن الخطأ لتقديم معلومات إضافية عن الخطأ للمستخدمين. يكون هذا الحقل مفعّلاً في التطبيق ليكون مفيدًا للمستخدمين لأنّ المتصفّحات لا يمكنها تقديم رسائل خطأ غنية في واجهة مستخدم مدمجة. على سبيل المثال: روابط للخطوات التالية أو معلومات للتواصل مع خدمة العملاء إذا أراد المستخدم معرفة المزيد من المعلومات حول تفاصيل الخطأ وكيفية إصلاحه، يمكنه الانتقال إلى الصفحة المقدَّمة من واجهة مستخدم المتصفّح للحصول على مزيد من التفاصيل. يجب أن يكون عنوان URL من الموقع الإلكتروني نفسه الذي يتبع موفِّر الهوية configURL.
  // id_assertion_endpoint response
  {
    "error" : {
      "code": "access_denied",
      "url" : "https://idp.example/error?type=access_denied"
    }
  }

تصنيفات الحسابات المخصّصة

باستخدام تصنيفات الحسابات المخصّصة، يمكن لموفّر الهوية إضافة تعليقات توضيحية إلى حسابات المستخدمين باستخدام التصنيفات، ويمكن لموفّر الاعتماد اختيار جلب الحسابات التي تتضمّن تصنيفات معيّنة فقط من خلال تحديد configURL لهذا التصنيف المحدّد. يمكن أن يكون ذلك مفيدًا عندما يحتاج مشرف الحملة إلى فلترة الحسابات حسب معايير معيّنة، على سبيل المثال، لعرض الحسابات المتعلّقة بالدور فقط، مثل "developer" أو "hr".

يمكن إجراء فلترة مشابهة باستخدام ميزتَي تلميح النطاق وتلميح تسجيل الدخول، وذلك من خلال تحديدهما في طلب navigator.credentials.get(). ومع ذلك، يمكن أن تصفّي تصنيفات الحسابات المخصّصة المستخدمين من خلال تحديد ملف الإعدادات، وهو أمر مفيد بشكل خاص عند استخدام عناوين URL متعددة للإعدادات. تختلف تصنيفات الحسابات المخصّصة أيضًا من حيث أنّها يتم توفيرها من خادم موفّر الهوية، بدلاً من موفّر الاعتماد، مثل إشارات تسجيل الدخول أو النطاق.

لنفترض أنّ هناك مزوّد خدمة مصادقة يريد التفريق بين حسابَي "developer" و"hr". لتحقيق ذلك، يجب أن يتيح موفِّر الهوية عناوين URL لإعدادات "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"
    }
  }
  • عند إجراء هذا الإعداد، يجب أن يتضمّن ملف well-known accounts_endpoint وlogin_url للسماح بعناوين configURL متعددة:
  {
    "provider_urls": [ "https://idp.example/fedcm.json" ],
    "accounts_endpoint": "https://idp.example/accounts",
    "login_url": "https://idp.example/login"
  }
  • تُعرِض نقطة نهاية حسابات موفّر الهوية المشترَك (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"]
    }]
  }

عندما يريد مقدّم خدمات الدفع السماح لمستخدمي "hr" بتسجيل الدخول، يمكنه تحديد configURL https://idp.example/hr/fedcm.json في طلب navigator.credentials.get():

  let { token } = await navigator.credentials.get({
    identity: {
      providers: [{
        clientId: '1234',
        nonce: '234234',
        configURL: 'https://idp.example/hr/fedcm.json',
      },
    }
  });

ونتيجةً لذلك، لا يتوفّر سوى رقم تعريف الحساب 4567 للمستخدم من أجل تسجيل الدخول. يخفي المتصفّح رقم تعريف الحساب 123 بدون إشعار المستخدم حتى لا يتم تزويده بحساب غير متوافق مع موفِّر الهوية (IdP) على هذا الموقع الإلكتروني.

  • التصنيفات هي سلاسل. إذا كانت مصفوفة labels أو حقل include يتضمّنان عنصرًا غير سلسلة، يتم تجاهله.
  • في حال عدم تحديد أي تصنيفات في configURL، سيتم عرض جميع الحسابات في أداة اختيار حسابات FedCM.
  • في حال عدم تحديد أي تصنيفات لحساب، لن يتم عرضه في أداة اختيار الحسابات إلا إذا لم تحدّد configURL أيضًا تصنيفًا.
  • إذا لم يتطابق أي حساب مع التصنيف المطلوب في الوضع التلقائي (على غرار ميزة "تلميح النطاق")، يعرض مربّع حوار FedCM طلب تسجيل الدخول، ما يسمح للمستخدم بتسجيل الدخول إلى حساب موفِّر الهوية. في الوضع النشط، يتم فتح النافذة المنبثقة لتسجيل الدخول مباشرةً.

إلغاء ربط نقطة النهاية

من خلال استدعاء IdentityCredential.disconnect()، يُرسِل المتصفّح طلبًا من مصدر مختلف لملف تعريف ارتباط POST يحتوي على SameSite=None ونوع محتوى هو application/x-www-form-urlencoded إلى نقطة نهاية القطع هذه مع المعلومات التالية:

الموقع الوصف
account_hint تلميح لحساب موفِّر الهوية (IdP)
client_id معرّف العميل لمسؤول المعالجة
  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. افصل حساب المستخدم عن نقطة الربط.
  6. يجب الردّ على المتصفّح بمعلومات حساب المستخدم المحدّد بتنسيق JSON.

في ما يلي مثال على حِمل JSON للاستجابة:

  {
    "account_id": "account456"
  }

بدلاً من ذلك، إذا أراد موفِّر الهوية أن يُلغي المتصفّح ربط جميع الحسابات المرتبطة بموفِّر الموافقة، يجب تمرير سلسلة لا تتطابق مع أي رقم تعريف حساب، على سبيل المثال "*".

نقطة نهاية البيانات الوصفية للعميل

تُعرِض نقطة نهاية البيانات الوصفية للعميل في موفِّر الهوية البيانات الوصفية للطرف الموثوق به، مثل سياسة الخصوصية وبنود الخدمة ورموز الشعار الخاصة بالطرف الموثوق به. على موفّري خدمات الربط تقديم روابط إلى سياسة الخصوصية وبنود الخدمة لموفّر الهوية مسبقًا. يتم عرض هذه الروابط في مربّع حوار تسجيل الدخول عندما لا يكون المستخدم مسجّلاً في موفِّر خدمات الربط (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 لسياسة خصوصية موفّر المحتوى
terms_of_service_url (اختياري) عنوان 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 لصفحة تسجيل الدخول

تُستخدَم نقطة النهاية هذه للسماح للمستخدم بتسجيل الدخول إلى موفِّر الهوية.

باستخدام واجهة برمجة التطبيقات Login Status API، يجب أن يُعلم موفِّر الهوية المتصفح بحالة تسجيل دخول المستخدم. ومع ذلك، قد لا تكون الحالة متزامنة، مثل عند انتهاء صلاحية الجلسة. في مثل هذا السيناريو، يمكن للمتصفّح السماح للمستخدم بتسجيل الدخول إلى موفِّر الهوية ديناميكيًا من خلال عنوان URL لصفحة تسجيل الدخول الذي تم تحديده باستخدام login_url في ملف إعدادات موفِّر الهوية.

يعرض مربّع حوار FedCM رسالة تقترح تسجيل الدخول، كما هو موضّح في الصورة التالية.

A
مربّع حوار FedCM يقترح تسجيل الدخول إلى موفِّر الهوية (IdP)

عندما ينقر المستخدم على الزر متابعة، يفتح المتصفّح نافذة منبثقة لصفحة تسجيل الدخول إلى موفِّر الهوية.

مثال على مربّع حوار FedCM
مثال على مربّع حوار يظهر بعد النقر على زر تسجيل الدخول إلى موفِّر الهوية (IdP).

مربّع الحوار هو نافذة متصفح عادية تحتوي على ملفات تعريف ارتباط الطرف الأول. إنّ أيّ مما يحدث داخل مربّع الحوار متروك لمسؤول عن إدارة الهوية، ولا تتوفّر أيّ معرّفات نوافذ لتقديم طلب تواصل بين مصدرَين مختلفَين إلى صفحة مقدّم خدمات الربط. بعد تسجيل دخول المستخدم، يجب أن ينفّذ موفِّر الهوية ما يلي:

  • أرسِل رأس Set-Login: logged-in أو استخدِم واجهة برمجة التطبيقات navigator.login.setStatus("logged-in") لإعلام المتصفّح بأنّه تم تسجيل دخول المستخدم.
  • اتصل بالرقم IdentityProvider.close() لإغلاق مربّع الحوار.
يُسجِّل المستخدِم الدخول إلى مقدّم خدمات المراجعة بعد تسجيل الدخول إلى موفِّر الهوية باستخدام FedCM.

إبلاغ المتصفّح بحالة تسجيل دخول المستخدم

Login Status API هي آلية يُعلم فيها الموقع الإلكتروني، خاصةً موفِّر الهوية، المتصفّح بحالة تسجيل دخول المستخدم على موفِّر الهوية. باستخدام واجهة برمجة التطبيقات هذه، يمكن للمتصفّح تقليل الطلبات غير الضرورية إلى موفّر الهوية والحدّ من الهجمات المحتملة المتعلّقة بالتوقيت.

يمكن لموفّري الهوية إرسال حالة تسجيل دخول المستخدم إلى المتصفّح من خلال إرسال عنوان HTTP أو من خلال طلب واجهة برمجة تطبيقات JavaScript عندما يكون المستخدم مسجّلاً الدخول إلى موفّر الهوية أو عندما يكون قد سجّل الخروج من جميع حسابات موفّر الهوية. بالنسبة إلى كل موفِّر هوية (IdP) (يتم تحديده من خلال عنوان URL لملف الإعدادات)، يحتفظ المتصفّح بمتغيّر ثلاثي الحالات يمثّل حالة تسجيل الدخول بالقيم المحتمَلة التالية:

  • logged-in
  • logged-out
  • unknown (تلقائي)
حالة تسجيل الدخول الوصف
logged-in عندما يتم ضبط حالة تسجيل دخول المستخدم على logged-in، يُجري مقدّم طلب الربط الذي يتصل بـ FedCM طلبات إلى نقطة نهاية حسابات موفِّر الهوية ويعرض الحسابات المتاحة للمستخدم في مربّع حوار FedCM.
logged-out عندما تكون حالة تسجيل دخول المستخدم هي logged-out، يتعذّر الاتصال بواجهة برمجة التطبيقات FedCM بدون إرسال طلب إلى نقطة نهاية حسابات موفِّر الهوية.
unknown (تلقائي) يتم ضبط الحالة unknown قبل أن يرسل موفّر الهوية إشارة باستخدام Login Status API. عندما تكون الحالة unknown، يُرسل المتصفّح طلبًا إلى نقطة نهاية حسابات موفِّر الهوية ويُعدّل الحالة استنادًا إلى الاستجابة الواردة من نقطة نهاية الحسابات.

للإشارة إلى أنّ المستخدم سجّل الدخول، أرسِل عنوان HTTP‏ Set-Login: logged-in في مسار تنقّل من المستوى الأعلى أو طلب مورد فرعي على الموقع نفسه في مصدر موفِّر idenity provider:

  Set-Login: logged-in

بدلاً من ذلك، يمكنك استدعاء طريقة JavaScript navigator.login.setStatus('logged-in') من مصدر موفِّر الهوية (IdP) في تنقّل على مستوى أعلى:

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

سيتم ضبط حالة تسجيل دخول المستخدم على logged-in.

للإشارة إلى أنّه تم تسجيل خروج المستخدم من جميع حساباته، أرسِل رأس HTTP‏ Set-Login: logged-out في تنقّل على مستوى أعلى أو طلب مورد فرعي على الموقع نفسه في مصدر موفِّر الهوية:

  Set-Login: logged-out

بدلاً من ذلك، يمكنك استدعاء واجهة برمجة التطبيقات JavaScript navigator.login.setStatus('logged-out') من مصدر موفِّر الهوية في مسار تنقّل من المستوى الأعلى:

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

سيتم ضبط حالة تسجيل دخول المستخدم على logged-out.

يتم ضبط الحالة unknown قبل أن يرسل موفّر الهوية إشارة باستخدام واجهة برمجة التطبيقات Login Status API. يُرسل المتصفّح طلبًا إلى نقطة نهاية حسابات موفِّر الهوية ويُعدّل الحالة استنادًا إلى الاستجابة الواردة من نقطة نهاية الحسابات:

  • إذا كانت نقطة النهاية تعرض قائمة بالحسابات النشطة، عدِّل الحالة إلى logged-in وافتح مربّع حوار FedCM لعرض هذه الحسابات.
  • إذا لم تُعرِض نقطة النهاية أي حسابات، عدِّل الحالة إلى logged-out و أوقِف طلب FedCM.

السماح للمستخدم بتسجيل الدخول من خلال عملية تسجيل دخول ديناميكية

على الرغم من أنّ موفّر الهوية (IdP) يواصل إبلاغ المتصفّح بحالة تسجيل دخول المستخدم، قد لا تكون البيانات متزامنة، مثلما يحدث عند انتهاء صلاحية الجلسة. يحاول المتصفّح إرسال طلب مزوّد ببيانات اعتماد إلى نقطة نهاية الحسابات عندما تكون حالة تسجيل الدخول هي logged-in، ولكن لا يعرض الخادم أي حسابات لأنّ الجلسة لم تعُد متوفّرة. في مثل هذا السيناريو، يمكن للمتصفّح السماح للمستخدم بشكل ديناميكي بتسجيل الدخول إلى موفِّر الهوية من خلال نافذة منبثقة.

تنفيذ FedCM بصفتها جهة محظورة

بعد توفّر إعدادات موفِّر الهوية ونقاط النهاية، يمكن لموفِّري خدمات الربط الاتصال بـ navigator.credentials.get() لطلب السماح للمستخدمين بتسجيل الدخول إلى موفِّر خدمات الربط باستخدام موفِّر الهوية.

قبل طلب البيانات من واجهة برمجة التطبيقات، عليك التأكّد من أنّ FedCM متاح في browser العميل. للتحقّق من توفّر FedCM، عليك تضمين هذا الرمز في عملية تنفيذ FedCM:

  if ('IdentityCredential' in window) {
    // If the feature is available, take action
  } else {
    // FedCM is not supported, use a different identity solution
  }

للسماح للمستخدمين بتسجيل الدخول إلى موفِّر الهوية (IdP) على مقدّم الخدمة (RP) باستخدام FedCM، يمكن لمقدّم الخدمة (RP) الاتصال بـ navigator.credentials.get()، على سبيل المثال:

  const credential = await navigator.credentials.get({
    identity: {
      context: 'signin',
      providers: [{
        configURL: 'https://accounts.idp.example/config.json',
        clientId: '********',
        mode: 'active',
        params: {
          nonce: '******'
        }
      }]
    }
  });
  const { token } = credential;

سمة السياق

باستخدام السمة الاختيارية context، يمكن لـ RP تعديل السلسلة في واجهة مستخدم مربّع حوار FedCM (على سبيل المثال، "تسجيل الدخول إلى rp.example…" أو "استخدام idp.example…") لاستيعاب سياقات المصادقة المحدّدة مسبقًا، على سبيل المثال. يمكن أن تحتوي السمة context على القيم التالية:

  • signin (تلقائي)
  • signup
  • use
مخطّط بياني يوضّح مكوّنات واجهة المستخدم في مربّع حوار FedCM: يظهر رمز في أعلى يمين الصفحة. على يسار الرمز، يظهر مكوّن سياق يعرض الرسالة "تسجيل الدخول إلى RP باستخدام موفِّر الهوية". في أسفل الشاشة، يظهر زر "متابعة" يتضمّن نصًا ولون خلفية مخصّصَين.
كيفية تطبيق العلامة التجارية على مربّع حوار FedCM

على سبيل المثال، سيؤدي ضبط context على use إلى ظهور الرسالة التالية:

مربّع حوار FedCM يعرض رسالة سياق مخصّصة: بدلاً من "تسجيل الدخول" باستخدام FedCM، تعرض رسالة السياق "استخدام" FedCM.
مربّع حوار FedCM يعرض رسالة سياق مخصّصة

يعالج المتصفّح حالات استخدام الاشتراك وتسجيل الدخول بشكلٍ مختلف استنادًا إلى توفّر approved_clients في الاستجابة من نقطة نهاية قائمة الحسابات. لن يعرض المتصفّح نص بيان الإفصاح "للمتابعة مع ...." إذا سبق للمستخدم الاشتراك في سياسة الخصوصية.
تستخدِم السمة providers صفيفًا من عناصر IdentityProvider التي تتضمّن السمات التالية:

سمة "مقدّمو الخدمة"

تأخذ السمة providers صفيفًا من عناصر IdentityProvider التي تحتوي على السمات التالية:

الموقع الوصف
configURL (مطلوب) المسار الكامل لملف إعداد موفِّر الهوية
clientId (مطلوب) معرّف عميل مقدّم الخدمة، الذي يصدره موفِّر الهوية.
nonce (اختياري) سلسلة عشوائية لضمان إصدار الردّ لهذا الطلب المحدّد. منع هجمات إعادة التشغيل
loginHint (اختياري) من خلال تحديد إحدى قيم login_hints المقدَّمة من نقاط نهاية الحسابات، يعرِض مربّع حوار FedCM الحساب المحدّد بشكل انتقائي.
domainHint (اختياري) من خلال تحديد إحدى قيم domain_hints التي يوفّرها نقاط نهاية الحسابات، يعرِض مربّع حوار FedCM الحساب المحدّد بشكل انتقائي.
mode (اختياري) سلسلة تحدِّد وضع واجهة المستخدم في FedCM يمكن أن تكون إحدى القيم التالية:
  • "active": يجب أن يبدأ طلب FedCM من خلال تفاعل المستخدم (مثل النقر على زر).
  • "passive": سيتم بدء طلب FedCM بدون تفاعل مباشر من المستخدم.
يمكنك الاطّلاع على الصفحة الإجمالية لمعرفة المزيد من المعلومات عن الفرق بين الوضعَين النشط والسلبي.

ملاحظة: تتوفّر المَعلمة mode في الإصدار 132 من Chrome.
fields (اختياري) صفيف من السلاسل التي تحدّد معلومات المستخدم ("الاسم" و"البريد الإلكتروني" و"الصورة") التي يحتاج إليها مقدّم طلب الاعتماد من موفّر الهوية لمشاركتها معه.
ملاحظة: تتوفّر واجهة برمجة التطبيقات Field API في الإصدار 132 من Chrome والإصدارات الأحدث.
parameters (اختياري) عنصر مخصّص يسمح بتحديد مَعلمات مفتاح/قيمة إضافية:
  • scope: قيمة سلسلة تحتوي على أذونات إضافية يحتاجها مقدّم الطلب، على سبيل المثال "drive.readonly calendar.readonly"
  • nonce: سلسلة عشوائية لضمان إصدار الردّ لهذا الطلب المحدّد. منع هجمات إعادة التشغيل
  • مَعلمات مخصّصة أخرى للقيم/المفاتيح

ملاحظة: تتوفّر ميزة parameters في الإصدار 132 من Chrome والإصدارات الأحدث.

وضع النشاط

تتوافق FedCM مع إعدادات مختلفة لوضع تجربة المستخدم. الوضع التلقائي هو الوضع التلقائي، ولا يحتاج المطوّرون إلى ضبطه.

لاستخدام FedCM في الوضع النشط:

  1. تحقَّق من توفّر الميزة في متصفّح المستخدم.
  2. يمكنك استدعاء واجهة برمجة التطبيقات باستخدام إيماءة عابرة للمستخدم، مثل النقر على زر.
  3. نقْل المَعلمة mode إلى طلب البيانات من واجهة برمجة التطبيقات:
  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'
      }
    });
  }

رمز مخصّص في وضع النشاط

يسمح "الوضع النشط" لموفّري خدمات المصادقة بضمّ رمز الشعار الرسمي لموفّر خدمات الربط مباشرةً في استجابة نقطة نهاية البيانات الوصفية للعميل. على موفّر المحتوى الترويجي تقديم بيانات علامته التجارية مسبقًا.

استدعاء FedCM من داخل إطار iframe متعدد المصادر

يمكن استدعاء FedCM من داخل إطار iframe من مصدر مختلف باستخدام سياسة أذونات identity-credentials-get، إذا كان الإطار الرئيسي يسمح بذلك. للقيام بذلك، أضِف السمة allow="identity-credentials-get" إلى علامة iframe على النحو التالي:

  <iframe src="https://fedcm-cross-origin-iframe.glitch.me" allow="identity-credentials-get"></iframe>

يمكنك الاطّلاع على آلية عمل هذه الميزة في مثال.

اختياريًا، إذا أرادت الإطار الرئيسي تقييد مصادر الاتصال بـ FedCM، أرسِل رأس Permissions-Policy مع قائمة بالمصادر المسموح بها.

  Permissions-Policy: identity-credentials-get=(self "https://fedcm-cross-origin-iframe.glitch.me")

يمكنك الاطّلاع على مزيد من المعلومات عن آلية عمل "سياسة الأذونات" في مقالة التحكّم في ميزات المتصفّح باستخدام "سياسة الأذونات".

Login Hint API

باستخدام "ملاحظة تسجيل الدخول"، يمكن لمسؤول المعالجة أن يقترح الحساب الذي يجب أن يسجّل المستخدم الدخول باستخدامه. يمكن أن يكون ذلك مفيدًا لإعادة مصادقة المستخدمين الذين لا يعرفون حسابهم السابق.

يمكن لتطبيقات RP عرض حساب معيّن بشكل انتقائي من خلال استدعاء navigator.credentials.get() باستخدام السمة loginHint مع إحدى قيم login_hints التي تم جلبها من نقطة نهاية قائمة الحسابات، كما هو موضّح في نموذج الرمز البرمجي التالي:

  return await navigator.credentials.get({
    identity: {
      providers: [{
        configURL: 'https://idp.example/manifest.json',
        clientId: '123',
        // Accounts endpoint can specify a 'login_hints' array for an account.
        // When RP specifies a 'exampleHint' value, only those accounts will be
        // shown to the user whose 'login_hints' array contains the 'exampleHint'
        // value
        loginHint : 'exampleHint'
      }]
    }
  });

عندما لا تتطابق أي حسابات مع loginHint، يعرض مربّع حوار FedCM طلب تسجيل الدخول، الذي يسمح للمستخدم بتسجيل الدخول إلى حساب موفِّر الهوية (IdP) يتطابق مع التلميح الذي طلبه موفِّر الموارد (RP). عندما ينقر المستخدم على الطلب، يتم فتح نافذة منبثقة تتضمّن عنوان URL لتسجيل الدخول المحدّد في ملف الإعدادات. بعد ذلك، تتم إضافة مَعلمات طلب البحث عن تلميح تسجيل الدخول وتلميح النطاق إلى الرابط.

Domain Hint API

يمكن لمسؤولي الحسابات المرجعية عرض الحسابات المرتبطة بنطاق معيّن فقط بشكل انتقائي. يمكن أن يكون ذلك مفيداً لمسؤولي الحسابات المحدودين بنطاق شركة.

لعرض حسابات نطاق معيّنة فقط، يجب أن يستدعي RP navigator.credentials.get() مع السمة domainHint مع إحدى قيم domain_hints التي تم جلبها من نقطة نهاية قائمة الحسابات، كما هو موضّح في المثال التالي للرمز البرمجي:

  return await navigator.credentials.get({
    identity: {
      providers: [{
        configURL: 'https://idp.example/manifest.json',
        clientId: 'abc',
        // Accounts endpoint can specify a 'domain_hints' array for an account.
        // When RP specifies a '@domain.example' value, only those accounts will be
        // shown to the user whose 'domain_hints' array contains the
        // '@domain.example' value
        domainHint : '@domain.example'
      }]
    }
  });

عندما لا تتطابق أي حسابات مع domainHint، يعرض مربّع حوار FedCM طلب تسجيل الدخول، الذي يسمح للمستخدم بتسجيل الدخول إلى حساب موفِّر الهوية (IdP) يتطابق مع التلميح الذي طلبه موفِّر الموارد (RP). عندما ينقر المستخدم على الطلب، يتم فتح نافذة منبثقة تتضمّن عنوان URL لتسجيل الدخول المحدّد في ملف الإعدادات. بعد ذلك، تتم إضافة مَعلمات طلب البحث عن تلميح تسجيل الدخول وتلميح النطاق إلى الرابط.

مثال على طلب تسجيل الدخول عندما لا تتطابق أي حسابات مع domainHint
مثال على طلب تسجيل الدخول عندما لا تتطابق أي حسابات مع domainHint

المعلمات المخصصة

تتيح ميزة "المَعلمات المخصّصة" لـ RP تقديم مَعلمات إضافية من النوع "مفتاح/قيمة" إلى نقطة نهاية تأكيد الهوية. باستخدام Parameters API، يمكن لموفّري خدمات الربط تمرير مَعلمات إضافية إلى موفّر الهوية لطلب أذونات للموارد التي تتجاوز عملية تسجيل الدخول الأساسية. يمكن أن يكون تمرير مَعلمات إضافية مفيدًا في السيناريوهات التالية:

  • على مقدّم الخدمة طلب أذونات إضافية ديناميكيًا لدى موفّر الهوية، مثل عنوان إرسال الفواتير أو إذن الوصول إلى التقويم. يمكن للمستخدم تفويض هذه الأذونات من خلال مسار تجربة مستخدم يتحكّم فيه موفِّر الهوية ويتم تشغيله باستخدام ميزة "متابعة"، وسيشارك موفِّر الهوية هذه المعلومات بعد ذلك.

لاستخدام واجهة برمجة التطبيقات، يضيف المعالج المرجعي للمكالمات مَعلمات إلى السمة params كعنصر في طلب navigator.credentials.get():

  let {token} = await navigator.credentials.get({
    identity: {
      providers: [{
        clientId: '1234',
        configURL: 'https://idp.example/fedcm.json',
        // Key/value pairs that need to be passed from the
        // RP to the IdP but that don't really play any role with
        // the browser.
        params: {
          IDP_SPECIFIC_PARAM: '1',
          foo: 'BAR'
        }
      },
    }
  });

سيترجم المتصفّح هذا تلقائيًا إلى طلب POST موجَّه إلى موفِّر الهوية مع المَعلمات ككائن مُسلسل بتنسيق 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&params=%22%7B%5C%22IDP_SPECIFIC_PARAM%5C%22%3A1%2C%5C%22foo%5C%22%3A%5C%22BAR%5C%22%7D%22.

إذا كان مقدّم الخدمة يحتاج إلى أي أذونات إضافية، يمكن لموفّر الهوية تقديم رابط إعادة توجيه. على سبيل المثال، في node.js:

  if (rpRequestsPermissions) {
    // Response with a URL if the RP requests additional permissions
    return res.json({
      continue_on: '/example-redirect',
    });
  }

الحقول

يمكن لمسؤول المعالجة تحديد معلومات المستخدم (أيّ مجموعة من الاسم وعنوان البريد الإلكتروني وصورة الملف الشخصي) التي يحتاج إلى أن يشاركها معك موفِّر الهوية. سيتم تضمين المعلومات المطلوبة في واجهة مستخدم بيان الإفصاح في مربّع حوار FedCM. ستظهر للمستخدم رسالة لإعلامه بأنّ idp.example ستشارك المعلومات المطلوبة مع rp.example إذا اختار المستخدم تسجيل الدخول.

مربّع حوار للوضع النشط في FedCM يعرض رسالة إفصاح للمتابعة، سيشارك مقدّم خدمة تحديد الهوية عنوان البريد الإلكتروني للمستخدم وصورة ملفه الشخصي مع الموقع الإلكتروني.
رسالة الإفصاح في الوضع النشط: يطلب مقدّم طلب المعالجة من موفِّر الهوية مشاركة عنوان البريد الإلكتروني للمستخدم وصورة ملفه الشخصي فقط.

لاستخدام ميزة "الحقول"، على RP إضافة صفيف fields في طلب navigator.credentials.get(). يمكن أن تحتوي الحقول على أيّ ترتيب من name وemail وpicture. ويمكن توسيع نطاق ذلك ليشمل المزيد من القيم في المستقبل. سيظهر الطلب الذي يتضمّن fields على النحو التالي:

  let { token } = await navigator.credentials.get({
    identity: {
      providers: [{
        // RP requests the IdP to share only user email and profile picture
        fields: [ 'email', 'picture'],
        clientId: '1234',
        configURL: 'https://idp.example/fedcm.json',

      },
    }
  });

سيترجم المتصفّح هذا الطلب تلقائيًا إلى طلب HTTP موجَّه إلى نقطة نهاية بيان الهوية التي تتضمّن المَعلمة fields التي حدّدها موفِّر الربط، مع الحقول التي أفصح عنها المتصفّح للمستخدم في المَعلمة 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 صفيفًا فارغًا، سيتخطّى وكيل المستخدم واجهة مستخدم بيان الإفصاح.

مربّع حوار الوضع التلقائي لـ FedCM لا يعرض رسالة واجهة مستخدم الإفصاح
لا يتم عرض رسالة الإفصاح في الوضع التلقائي. في مسار الزر، يتم تخطّي واجهة مستخدم بيان الإفصاح بالكامل.

وينطبق ذلك حتى إذا كان الردّ من نقطة نهاية حسابات لا يحتوي على رقم تعريف عميل يتطابق مع مقدّم الخدمة في 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

عرض رسالة خطأ

في بعض الأحيان، قد يتعذّر على موفِّر الهوية إصدار رمز مميّز لأسباب مشروعة، مثل عندما يكون العميل غير مصرَّح له أو عندما يكون الخادم غير متاح مؤقتًا. إذا كان ردّ موفِّر الهوية هو "خطأ"، يمكن لمسؤول المعالجة رصده، ويمكن لمتصفّح Chrome إعلام المستخدم من خلال عرض واجهة مستخدِم المتصفّح التي تتضمّن معلومات الخطأ المقدَّمة من موفِّر الهوية.

A
مربّع حوار FedCM يعرض رسالة الخطأ بعد تعذُّر محاولة تسجيل دخول المستخدم تكون السلسلة مرتبطة بنوع الخطأ.
  try {
    const cred = await navigator.credentials.get({
      identity: {
        providers: [
          {
            configURL: 'https://idp.example/manifest.json',
            clientId: '1234',
          },
        ],
      }
    });
  } catch (e) {
    const code = e.code;
    const url = e.url;
  }

إعادة مصادقة المستخدمين تلقائيًا بعد المصادقة الأولية

يمكن أن تسمح ميزة إعادة المصادقة التلقائية في إطار إدارة الهوية وإمكانية الوصول (FedCM) (يُشار إليها اختصارًا باسم "إعادة المصادقة التلقائية") للمستخدمين بإعادة المصادقة تلقائيًا عند عودتهم بعد المصادقة الأولية باستخدام FedCM. يشير "المصادقة المبدئية" هنا إلى أنّ المستخدم ينشئ حسابًا أو يسجّل الدخول إلى الموقع الإلكتروني للمورّد المصدق من خلال النقر على الزر "متابعة باسم..." في مربّع حوار تسجيل الدخول إلى FedCM للمرة الأولى في مثيل المتصفّح نفسه.

على الرغم من أنّ تجربة المستخدم الصريحة تكون منطقية قبل أن ينشئ المستخدم الحساب الموحّد لمنع التتبّع (وهو أحد الأهداف الرئيسية لإدارة الهوية وإمكانية الوصول)، تكون هذه التجربة مزعجة بلا داعٍ بعد أن يمرّ المستخدم بها مرة واحدة: بعد منح المستخدم الإذن للسماح بالتواصل بين مقدّم الخدمة ومسؤول تحديد الهوية، لا تعود هناك أي فائدة من الخصوصية أو الأمان في فرض تأكيد صريح آخر من العميل لشيء سبق أن أقرّ به.

من خلال إعادة المصادقة التلقائية، يغيّر المتصفّح سلوكه استنادًا إلى الخيار الذي تحديده لـ 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 هو خاصية في واجهة برمجة التطبيقات لإدارة بيانات الاعتماد، ويتصرف بالطريقة نفسها التي يتصرف بها PasswordCredential و FederatedCredential ، وهو متوافق جزئيًا مع PublicKeyCredential أيضًا. يقبل الحقل القيم الأربع التالية:

  • 'optional'(الإعداد التلقائي): إعادة المصادقة التلقائية إن أمكن، وتتطلّب التوسّط في حال عدم توفّرها. ننصحك باختيار هذا الخيار في صفحة تسجيل الدخول.
  • 'required': تتطلّب هذه الميزة دائمًا التوسّط للمتابعة، على سبيل المثال، النقر على الزرّ "متابعة" في واجهة المستخدم. حدِّد هذا الخيار إذا كان من المتوقّع من المستخدمين منح الإذن صراحةً في كل مرة يحتاجون فيها إلى المصادقة.
  • 'silent': إعادة المصادقة التلقائية إن أمكن، أو تعذُّر المصادقة بدون الحاجة إلى توسّط في حال عدم توفّر المصادقة ننصحك باختيار هذا الخيار في الصفحات التي تريد فيها إبقاء المستخدمين مسجّلين الدخول، ولكنها ليست صفحة تسجيل الدخول المخصّصة، مثل صفحة سلعة على موقع إلكتروني لشحن البضائع أو صفحة مقالة على موقع إلكتروني لأخبار.
  • 'conditional': يُستخدَم مع WebAuthn ولا يتوفّر مع FedCM في الوقت الحالي.

من خلال هذا الطلب، تحدث إعادة المصادقة التلقائية في الحالات التالية:

  • ميزة FedCM متاحة للاستخدام. على سبيل المثال، لم يوقف المستخدم FedCM إما بشكل عام أو للمسؤول عن نقطة الاتصال في الإعدادات.
  • استخدم المستخدم حسابًا واحدًا فقط مع FedCM API لتسجيل الدخول إلى الموقع الإلكتروني على هذا المتصفّح.
  • سجَّل المستخدم الدخول إلى موفِّر الهوية باستخدام هذا الحساب.
  • لم يتم إجراء إعادة المصادقة التلقائية خلال آخر 10 دقائق.
  • لم يطلب مقدّم الطلب navigator.credentials.preventSilentAccess() تسجيل الدخول مجددًا بعد تسجيل الدخول السابق.

عند استيفاء هذه الشروط، تبدأ محاولة إعادة مصادقة المستخدم تلقائيًا فور استدعاء navigator.credentials.get() FedCM.

عندما يكون mediation: optional، قد تكون إعادة المصادقة التلقائية غير متاحة لأسباب يعرفها المتصفّح فقط. ويمكن لمسؤول المعالجة التحقّق مما إذا تم إجراء إعادة المصادقة التلقائية من خلال examining the isAutoSelected property.

ويساعد ذلك في تقييم أداء واجهة برمجة التطبيقات وتحسين تجربة المستخدم وفقًا لذلك. وفي حال عدم توفّر هذه الطريقة، قد يُطلب من المستخدم تسجيل الدخول من خلال mediation: required، وهو مسار يتضمّن mediation: required.

يعيد المستخدِم المصادقة تلقائيًا من خلال FedCM.

فرض التوسّط مع preventSilentAccess()

إنّ إعادة مصادقة المستخدمين تلقائيًا بعد تسجيل خروجهم مباشرةً لن توفّر تجربة مستخدم جيدة جدًا. لهذا السبب، تتضمّن FedCM فترة هدوء تبلغ 10 دقائق بعد إعادة المصادقة التلقائية لمنع هذا السلوك. وهذا يعني أنّ عملية إعادة المصادقة التلقائية تحدث مرة واحدة على الأكثر كل 10 دقائق ما لم يسجّل المستخدم الدخول مجددًا في مهلة تعادل 10 دقائق. يجب أن يطلب مقدّم الخدمة navigator.credentials.preventSilentAccess() طلبًا صريحًا من المتصفّح لإيقاف إعادة المصادقة التلقائية عندما يسجّل المستخدم الخروج من مقدّم الخدمة صراحةً، على سبيل المثال، من خلال النقر على زر تسجيل الخروج.

  function signout() {
    navigator.credentials.preventSilentAccess();
    location.href = '/signout';
  }

يمكن للمستخدمين إيقاف إعادة المصادقة التلقائية في الإعدادات.

يمكن للمستخدمين إيقاف إعادة المصادقة التلقائية من قائمة الإعدادات:

  • على متصفّح Chrome للكمبيوتر المكتبي، انتقِل إلى chrome://password-manager/settings > تسجيل الدخول تلقائيًا.
  • على متصفّح Chrome لأجهزة Android، افتح الإعدادات > مدير كلمات المرور > انقر على رمز الترس في أعلى يسار الشاشة > تسجيل الدخول تلقائيًا.

من خلال إيقاف التبديل، يمكن للمستخدم إيقاف سلوك إعادة المصادقة التلقائية بالكامل. يتم تخزين هذا الإعداد ومزامنته على جميع الأجهزة، إذا كان المستخدم مسجّلاً الدخول إلى حساب Google على نسخة Chrome وكانت المزامنة مفعّلة.

إلغاء ربط موفِّر الهوية بمسؤول المعالجة

إذا سجّل مستخدم الدخول إلى مقدّم الخدمة باستخدام موفِّر الهوية من خلال FedCM، يحفظ المتصفّح ملفًا شخصيًا على الجهاز كقائمة بالحسابات المرتبط بها. يمكن أن يبدأ RP عملية قطع الاتصال من خلال استدعاء الدالة IdentityCredential.disconnect(). يمكن استدعاء هذه الدالة من إطار RP من المستوى الأعلى. يجب أن يقدّم موفِّر الربط configURL وclientId المستخدَمَين ضمن موفِّر الهوية وaccountHint لإيقاف اتصال موفِّر الهوية. يمكن أن يكون تلميح حساب سلسلة عشوائية طالما أنّ نقطة نهاية إلغاء الربط يمكنها تحديد الحساب، على سبيل المثال، عنوان بريد إلكتروني أو رقم تعريف مستخدم لا يطابق بالضرورة رقم تعريف الحساب الذي قدّمته نقطة نهاية قائمة الحسابات:

  // 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. قد يُلقي هذا الوعد استثناءً للأسباب التالية:

  • لم يسجِّل المستخدم الدخول إلى موفِّر الموارد باستخدام موفِّر الهوية من خلال FedCM.
  • يتمّ استدعاء واجهة برمجة التطبيقات من داخل إطار iframe بدون سياسة أذونات FedCM.
  • ‎configURL غير صالح أو لا يتضمّن نقطة نهاية لإيقاف الاتصال.
  • تعذّر التحقّق من سياسة أمان المحتوى (CSP).
  • هناك طلب في انتظار المراجعة لإلغاء الربط.
  • أوقف المستخدم ميزة FedCM في إعدادات المتصفّح.

عندما تعرض نقطة نهاية إلغاء الربط في موفِّر الهوية رداً، يتم إلغاء ربط موفِّر الهوية ومسؤول المعالجة في المتصفّح ويتم حلّ الوعد. يتم تحديد معرّف الحسابات التي تم إلغاء ربطها في الاستجابة من نقطة نهاية إلغاء الربط.