آخر الأخبار من FedCM: تجارب المصدر لحزمة Continuation API والمنح التلقائي لواجهة برمجة التطبيقات Storage Access API

بدءًا من Chrome 126، يمكن للمطوِّرين بدء تشغيل نسخة تجريبية من حزمة من ميزات Federated Credential Management API (FedCM) على أجهزة الكمبيوتر المكتبي، والتي تتيح بعض حالات استخدام التفويض. تتألف الحزمة من Continuation API و Parameters API، اللتين تتيحان تجربة مشابهة لمسار التفويض في OAuth تتضمن مربّع حوار الإذن المقدَّم من موفِّر الهوية (IdP). تتضمّن الحزمة أيضًا تغييرات أخرى، مثل Fields API وMultiple configURLs وCustom Account Labels. اعتبارًا من الإصدار 126 من Chrome، سنقدّم أيضًا فترة تجريبية لمصدر واجهة برمجة التطبيقات Storage Access API (SAA) التي تمنح طلبات SAA تلقائيًا إذا سجّل المستخدم بنجاح الدخول باستخدام FedCM في السابق.

الإصدار التجريبي: حزمة FedCM Continuation API

تتألف حزمة FedCM Continuation API من عدة إضافات FedCM:

Continuation API

يُسجِّل المستخدم الدخول إلى نقطة الربط ثم يمنح الإذن من خلال وضع الأزرار.

يمكنك الاطّلاع على عرض توضيحي لواجهة برمجة التطبيقات على Glitch.

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

عادةً ما تعرض نقطة نهاية بيان الهوية رمزًا مميزًا مطلوبًا لتأكيد هوية العميل.

{
  "token": "***********"
}

ومع ذلك، باستخدام Continuation API، يمكن أن تُعرِض نقطة نهاية continue_oncontinue_on التي تتضمّن مسارًا مطلقًا أو continue_on نسبيًا إلى نقطة نهاية 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 pop-up window:
  "continue_on": "/oauth/authorize?scope=..."
}

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

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

document.getElementById('allow_btn').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.close().

IdentityProvider.close();

إذا غيّر المستخدم حسابه في النافذة المنبثقة لأي سبب (على سبيل المثال، يقدّم موفِّر الهوية والخدمات (IdP) وظيفة "تبديل المستخدم"، أو في حالات التفويض)، يأخذ الإجراء resolve مَعلمة ثانية اختيارية تسمح بإجراء ما يلي:

IdentityProvider.resolve(token, {accountId: '1234');

Parameters API

تسمح Parameters API لـ RP بتقديم مَعلمات إضافية إلى نقطة نهاية ملف تعريف هوية العميل . باستخدام Parameters API، يمكن لموفّري خدمات الربط تمرير مَعلمات إضافية إلى موفّر الهوية لطلب أذونات للموارد التي تتجاوز عملية تسجيل الدخول الأساسية. يجب أن يسمح المستخدم بهذه الأذونات من خلال تدفق تجربة مستخدم يتحكم فيه موفِّر الهوية (idP) ويتم تشغيله عبر واجهة برمجة تطبيقات Continuation 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',
        ETC: 'MOAR',
        scope: 'calendar.readonly photos.write',
      }
    },
  }
});

يتمّ وضع param_ في بداية أسماء السمات في عنصر params. في المثال أعلاه، تحتوي سمة params على IDP_SPECIFIC_PARAM ك'1' وfoo ك'BAR' وETC ك'MOAR' وscope ك'calendar.readonly photos.write'. سيتم تحويل هذا العنوان إلى param_IDP_SPECIFIC_PARAM=1&param_foo=BAR&param_ETC=MOAR&param_scope=calendar.readonly%20photos.write في نص طلب HTTP:

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

account_id=123&client_id=client1234&nonce=234234&disclosure_text_shown=false&param_IDP_SPECIFIC_PARAM=1&param_foo=BAR&param_ETC=MOAR&param_scope=calendar.readonly%20photos.write

الحصول على الأذونات بشكل ديناميكي

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

لطلب التفويض ديناميكيًا باستخدام FedCM، يمكن لموفِّر الهوية (IdP) إجراء ما يلي:

  1. يمكنك طلب navigator.credentials.get() مع تضمين المعلَمات المطلوبة التي يمكن لموفِّر الهوية فهمها، مثل scope.
  2. تؤكّد نقطة نهاية تأكيد المعرّف أن المستخدم سبق أن سجّل الدخول ويردّ باستخدام عنوان URL continue_on.
  3. يفتح المتصفِّح نافذة منبثقة تعرض صفحة إذن موفِّر الهوية (idP) التي تطلب إذنًا إضافيًا يتطابق مع النطاقات المطلوبة.
  4. بعد أن يحصل موفِّر الهوية على إذن عبر IdentityProvider.resolve()، يتم إغلاق النافذة ويتلقّى طلب navigator.credentials.get() الأصلي من مقدّم الخدمة رمزًا مميّزًا ذا صلة أو رمز تفويض حتى يتمكّن مقدّم الخدمة من تبديله برمز مميّز مناسب للوصول.

واجهة برمجة التطبيقات للحقول

تسمح Fields API لموفّر المحتوى بالإعلان عن سمات الحساب المطلوب الحصول عليها من موفّر الهوية حتى يتمكّن المتصفّح من عرض واجهة مستخدم مناسبة للإفصاح في مربّع حوار FedCM، وتقع على عاتق موفّر الهوية مسؤولية تضمين الحقول المطلوبة في الرمز المرجعي الذي يتم إرجاعه. يمكنك مراعاة ذلك عند طلب "ملف شخصي أساسي" في OpenID Connect مقابل "النطاقات" في OAuth.

رسالة الإفصاح في وضع التطبيق المصغّر
رسالة الإفصاح في وضع التطبيقات المصغّرة
رسالة الإفصاح في وضع الزر
رسالة الإفصاح في وضع الأزرار

لاستخدام Fields API، أضِف معلَمات إلى السمة fields كمصفوفة في طلب navigator.credentials.get(). يمكن أن تحتوي الحقول على 'name' و'email' و'picture' في الوقت الحالي، ولكن يمكن توسيعها لتشمل المزيد من القيم في المستقبل.

سيظهر الطلب الذي يتضمّن fields على النحو التالي:

let { token } = await navigator.credentials.get({
  identity: {
    providers: [{
      fields: ['name', 'email', 'picture'],
      clientId: '1234',
      configURL: 'https://idp.example/fedcm.json',
      params: {
        scope: 'drive.readonly calendar.readonly',
      }
    },
  }
  mediation: 'optional',
});

يتضمّن طلب HTTP إلى نقطة نهاية تأكيد رقم التعريف مَعلمة fields التي حدّدها الجهة المحظورة، مع ضبط المَعلمة disclosure_text_shown على أنّها true إذا لم يكن هذا المستخدم هو مكرِّر الزيارة، والحقول التي كشف عنها المتصفّح للمستخدم في مَعلمة disclosure_shown_for:

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=true&fields=email,name,picture&disclosure_shown_for=email,name,picture

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

إذا كان fields صفيفًا فارغًا، سيظهر الطلب على النحو التالي:

let { token } = await navigator.credentials.get({
  identity: {
    providers: [{
      fields: [],
      clientId: '1234',
      configURL: 'https://idp.example/fedcm.json',
      params: {
        scope: 'drive.readonly calendar.readonly',
      }
    },
  }
  mediation: 'optional',
});

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

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

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

عناوين configURL المتعددة

تتيح عناوين URL المتعددة لموفّري الهوية إمكانية إضافة عدة ملفات إعداد لموفِّر الهوية من خلال تحديد accounts_endpoint وlogin_url في الملف المعروف بالطريقة نفسها المُتّبعة في ملفات الضبط.

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

يمكن أن يبدو ملف well-known الذي يتيح عناوين configURL متعددة على النحو التالي:

{
  "provider_urls": [ "https://idp.example/fedcm.json" ],
  "accounts_endpoint": "https://idp.example/accounts",
  "login_url": "https://idp.example/login"
}

ويسمح لنا ذلك بما يلي:

  1. الحفاظ على التوافق مع الإصدارات السابقة واللاحقة من الملفات المعروفة والإصدارات السابقة من المتصفّحات التي تم نشرها من قبل
  2. أن تتضمّن عددًا عشوائيًا من ملفات الإعداد، شرط أن تشير جميعها إلى accounts_endpoint وlogin_url نفسهما
  3. لا تتوفّر فرصة لإضافة معلومات الالتباس إلى طلب الجلب المزوّد ببيانات الاعتماد الذي يتم توجيهه إلى accounts_endpoint، لأنّه يجب تحديدها على مستوى ‎".well-known".

يُرجى العلم أنّ إتاحة عدة عناوين URL للإعداد هي إجراء اختياري، ويمكن أن تظلّ عمليات تنفيذ "المراسلة عبر السحابة الإلكترونية من Firebase" الحالية كما هي.

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

تسمح تصنيفات الحساب المخصّصة لموفّري idenityFedCM IdP بإضافة تعليقات توضيحية إلى الحسابات حتى يتمكّن موفّري خدمات الربط من فلترتها من خلال تحديد التصنيف فيملف الإعدادات. توفّرت إمكانية إجراء فلترة مشابهة باستخدام واجهة برمجة تطبيقات اقتراح النطاق وواجهة برمجة تطبيقات تلميح تسجيل الدخول من خلال تحديدهما في طلب navigator.credentials.get()، إلا أنّ "تصنيفات الحساب المخصّص" يمكنها فلترة المستخدمين من خلال تحديد ملف الإعداد، وهو أمر مفيد بشكل خاص عند استخدام عناوين configURL متعددة. وتختلف أيضًا تصنيفات الحسابات المخصّصة من حيث أنّها يتم توفيرها من خادم موفِّر الهوية (idP)، وليس من الجهة المحظورة، مثل تلميحات تسجيل الدخول أو النطاق.

مثال

يتوافق موفِّر الهوية مع عنوانَي configURL للمستهلك والمؤسسة على التوالي. يحتوي ملف إعدادات المستهلك على تصنيف 'consumer'، ويحتويملف إعدادات المؤسسة على تصنيف 'enterprise'.

باستخدام هذا الإعداد، يتضمّن ملف 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"
}

عند توفير accounts_endpoint في الملف المعروف، يتم تجاهل provider_urls. يمكن أن يشير RP مباشرةً إلى ملفات الإعدادات المعنية في طلب navigator.credentials.get().

يمكن العثور على ملف إعدادات المستهلك على https://idp.example/fedcm.json الذي يتضمّن سمة accounts التي تحدّد 'consumer' باستخدام include.

{
  "accounts_endpoint": "https://idp.example/accounts",
  "client_metadata_endpoint": "/client_metadata",
  "login_url": "https://idp.example/login",
  "id_assertion_endpoint": "/assertion",
  "accounts": {
    "include": "consumer"
  }
}

يوجد ملف الإعداد الخاص بالمؤسسات على العنوان https://idp.example/enterprise/fedcm.json، والذي يتضمّن السمة accounts التي تحدّد 'enterprise' باستخدام include.

{
  "accounts_endpoint": "https://idp.example/accounts",
  "client_metadata_endpoint": "/enterprise/client_metadata",
  "login_url": "https://idp.example/login",
  "id_assertion_endpoint": "/assertion",
  "accounts": {
    "include": "enterprise"
  }
}

تُعرِض نقطة نهاية حسابات العميل المشترَك لمزوّد الهوية (في هذا المثال 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": ["consumer"]
  }], [{
   "id": "4567",
   "given_name": "Jane",
   "name": "Jane Doe",
   "email": "jane_doe@idp.example",
   "picture": "https://idp.example/profile/4567",
   "labels": ["enterprise"]
  }]
}

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

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

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

مرحلة التجربة والتقييم: FedCM كإشارة ثقة لواجهة Storage Access API

سيبدأ الإصدار 126 من Chrome مرحلة التجربة والتقييم لإدخال واجهة برمجة التطبيقات FedCM كإشارة ثقة لواجهة برمجة التطبيقات Storage Access . من خلال هذا التغيير، يصبح منح الإذن المسبق من خلال FedCM سببًا وجيهًا للموافقة تلقائيًا على طلب الوصول إلى مساحة التخزين من خلال واجهات برمجة التطبيقات "الوصول إلى مساحة التخزين".

يكون ذلك مفيدًا عندما يريد إطار iframe مضمّن الوصول إلى موارد مخصّصة: على سبيل المثال، إذا كان idp.example مضمّنًا في rp.example ويحتاج إلى عرض مورد مخصّص. إذا فرض المتصفّح قيودًا على الوصول إلى ملفات تعريف الارتباط التابعة لجهات خارجية، حتى إذا كان المستخدم مسجِّلاً الدخول إلى rp.example باستخدام idp.example مع FedCM، لن يتمكّن إطار iframe المضمّن من idp.example من طلب موارد مخصّصة لأنّ الطلبات لن تتضمّن ملفات تعريف الارتباط التابعة لجهات خارجية.

لتحقيق ذلك، يجب أن يحصل idp.example على إذن الوصول إلى مساحة التخزين من خلال ملف div مضمّن في الموقع الإلكتروني، ولا يمكن الحصول على هذا الإذن إلا من خلال طلب div.

باستخدام FedCM كإشارة ثقة لواجهة برمجة التطبيقات Storage Access، لا تقبل عمليات التحقق من أذونات واجهة برمجة التطبيقات Storage Access API فقط منح الإذن الممنوح من خلال طلب الوصول إلى مساحة التخزين، بل تقبل أيضًا منح الإذن المقدَّم من خلال طلب FedCM.

// In top-level rp.example:

// Ensure FedCM permission has been granted.
const cred = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: 'https://idp.example/fedcm.json',
      clientId: '123',
    }],
  },
  mediation: 'optional',
});

// In an embedded IdP iframe:

// No user gesture is needed to call this, and the call will be auto-granted.
await document.requestStorageAccess();

// This returns `true`.
const hasAccess = await document.hasStorageAccess();

بعد تسجيل دخول المستخدم من خلال FedCM، يتم منح الإذن تلقائيًا طالما كانت مصادقة FedCM نشطة. هذا يعني أنه بمجرد إلغاء اتصال المستخدم، سيؤدي طلب الإذن إلى ظهور رسالة مطالبة.

المشاركة في مرحلة التجربة والتقييم

يمكنك تجربة حزمة واجهة برمجة التطبيقات Continuation API في FedCM محليًا من خلال تفعيل علامة Chrome chrome://flags#fedcm-authz في الإصدار 126 من Chrome أو إصدار أحدث. يمكنك أيضًا تجربة FedCM كإشارة ثقة لواجهة برمجة التطبيقات Storage Access API على الجهاز من خلال تفعيل #fedcm-with-storage-access-api على Chrome 126 أو الإصدارات الأحدث.

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

لتجربة حزمة FedCM Continuation API لميزة "متابعة المحادثة" ، أنشئ رمزَي مميّزَين لتجربة ميزة "متابعة المحادثة":

إذا كنت مهتمًا بتفعيل واجهة برمجة التطبيقات Continuation API مع تدفق الزر، يمكنك تفعيل التجربة الأصلية لواجهة برمجة التطبيقات لوضع الزر أيضًا:

لتجربة إطار عمل FedCM كإشارة ثقة في مرحلة التجربة والتقييم على واجهة برمجة التطبيقات Storage Access، اتّبِع الخطوات التالية:

من الإصدار Chrome 126، تتوفّر مرحلة التجربة والتقييم في حزمة Continuation API وFedCM كإشارة ثقة في مرحلة التجربة والتقييم في Storage Access API.

تسجيل فترة تجريبية لجهة خارجية في "المسؤول عن المعالجة"

  1. انتقِل إلى صفحة التسجيل في مرحلة التجربة والتقييم.
  2. انقر على الزر تسجيل واملأ النموذج لطلب رمز مميّز.
  3. أدخِل مصدر موفِّر خدمة المصادقة على أنّه مصدر الويب.
  4. تحقَّق من مطابقة الجهات الخارجية لإدراج الرمز المميّز باستخدام JavaScript في مصادر أخرى.
  5. انقر على إرسال.
  6. تضمين الرمز المميّز الصادر على موقع إلكتروني تابع لجهة خارجية

لتضمين الرمز المميّز على موقع إلكتروني تابع لجهة خارجية، أضِف الرمز التالي إلى مكتبة JavaScript أو حزمة تطوير البرامج (SDK) الخاصة بموفِّر الهوية والمعروضة من مصدر موفِّر الهوية.

const tokenElement = document.createElement('meta');
tokenElement.httpEquiv = 'origin-trial';
tokenElement.content = 'TOKEN_GOES_HERE';
document.head.appendChild(tokenElement);

استبدِل TOKEN_GOES_HERE برمزك المميّز.