بدءًا من Chrome 126، يمكن للمطوّرين بدء تشغيل نسخة تجريبية من حزمة من ميزات Federated Credential Management API لأجهزة الكمبيوتر المكتبي (FedCM) تتيح بعض حالات استخدام التفويض. تتكوّن الحزمة من واجهة برمجة التطبيقات Continuation API وواجهة برمجة التطبيقات parameters (المعلمات)، اللتين تتيحان تجربة شبيهة بتدفق تفويض OAuth تتضمن مربّع حوار الإذن الذي يقدِّمه موفِّر الهوية (IdP). تتضمن الحزمة أيضًا تغييرات أخرى مثل واجهة برمجة تطبيقات الحقول، وعناوين URL المتعددة للإعدادات المتعددة وتصنيفات الحساب المخصصة. من Chrome 126، نقدِّم أيضًا مرحلة تجريبية للمصدر للواجهة برمجة تطبيقات الوصول إلى مساحة التخزين (SAA) التي تمنح طلبات SAA تلقائيًا إذا سجَّل المستخدم الدخول بنجاح باستخدام برنامج FedCM في الماضي.
الإصدار التجريبي: حزمة FedCM Continuation API
تتألف حزمة واجهة برمجة تطبيقات Continuation API من FedCM من إضافات FedCM متعددة:
- واجهة برمجة تطبيقات Continuation
- واجهة برمجة التطبيقات للمعلَمات
- Fields API
- عدة configURLs
- تصنيفات الحساب المخصّصة
واجهة برمجة تطبيقات Continuation
يمكنك الاطّلاع على عرض توضيحي لواجهة برمجة التطبيقات على تطبيق Glitch.
تسمح Continuation API لنقطة نهاية تأكيد رقم التعريف لموفِّر الهوية بعرض عنوان URL الذي سيعرضه FedCM بشكل اختياري للسماح للمستخدم بمواصلة عملية تسجيل الدخول متعددة الخطوات. ويتيح ذلك لموفِّر الهوية أن يطلب من المستخدم منح أذونات الجهة الموثوق بها (RP) بخلاف ما هو ممكن في واجهة مستخدم FedCM الحالية، مثل الوصول إلى موارد المستخدم من جهة الخادم.
عادةً ما تعرض نقطة نهاية تأكيد رقم التعريف الرمز المميز المطلوب للمصادقة.
{
"token": "***********"
}
أمّا في واجهة برمجة التطبيقات Continuation API، فيمكن أن تعرض نقطة نهاية تأكيد رقم التعريف السمة 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();
إذا غيّر المستخدم لأي سبب من الأسباب حسابه في النافذة المنبثقة (على سبيل المثال، يوفّر موفِّر الهوية وظيفة "تبديل المستخدم" أو في حالات التفويض)، يأخذ استدعاء الحل وسيطة ثانية اختيارية تسمح بشيء مثل:
IdentityProvider.resolve(token, {accountId: '1234');
واجهة برمجة التطبيقات للمعلَمات
تسمح معلَمات واجهة برمجة التطبيقات للجهة المحظورة بتوفير معلَمات إضافية إلى نقطة نهاية تأكيد المعرِّف. باستخدام معلَمات واجهة برمجة التطبيقات، يمكن للجهات المحظورة تمرير معلَمات إضافية إلى موفِّر الهوية (idP) لطلب أذونات للموارد التي تتجاوز عملية تسجيل الدخول الأساسية. يجب أن يسمح المستخدم بهذه الأذونات من خلال تدفق تجربة مستخدم يتحكم فيه موفِّر الهوية (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',
}
},
}
});
تأتي أسماء السمات في الكائن params
مسبوقة بـ param_
. في المثال أعلاه، تحتوي سمة المَعلمات على IDP_SPECIFIC_PARAM
بالصيغة '1'
وfoo
على أنّها 'BAR'
وETC
و'MOAR'
وscope
بالصيغة 'calendar.readonly photos.write'
.
ستتم ترجمة ذلك إلى النص
param_IDP_SPECIFIC_PARAM=1¶m_foo=BAR¶m_ETC=MOAR¶m_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¶m_IDP_SPECIFIC_PARAM=1¶m_foo=BAR¶m_ETC=MOAR¶m_scope=calendar.readonly%20photos.write
الحصول على الأذونات ديناميكيًا
بوجه عام، يكون من المفيد للمستخدمين طلب الأذونات عند الحاجة إليها، بدلاً من طلب الأذونات عندما يرى المطوّر أنّها أسهل من حيث التنفيذ. على سبيل المثال، عند طلب الإذن بالوصول إلى الكاميرا عندما يكون المستخدم على وشك التقاط صورة، يُفضّل طلب الإذن فور انتقاله إلى الموقع الإلكتروني. تنطبق الممارسة نفسها على موارد الخادم. لا تطلب الأذونات إلا عندما تكون مطلوبة للمستخدم. يُعرَف هذا باسم "التفويض الديناميكي".
لطلب التفويض ديناميكيًا من خلال FedCM، يمكن لموفِّر الهوية إجراء ما يلي:
- يمكنك طلب
navigator.credentials.get()
مع تضمين المعلَمات المطلوبة التي يمكن لموفِّر الهوية فهمها، مثلscope
. - تؤكّد نقطة نهاية
تأكيد المعرّف
أن المستخدم سبق أن سجّل الدخول ويردّ باستخدام عنوان URL
continue_on
. - يفتح المتصفِّح نافذة منبثقة تعرض صفحة إذن موفِّر الهوية (idP) التي تطلب إذنًا إضافيًا يتطابق مع النطاقات المطلوبة.
- بعد أن يحصل موفّر الهوية على الإذن من خلال
IdentityProvider.resolve()
، يتم إغلاق النافذة ويحصل استدعاءnavigator.credentials.get()
الأصلي للجهة المحظورة على رمز مميّز ذي صلة أو رمز تفويض ليتمكّن الجهة المحظورة من استبدالها برمز دخول مناسب.
واجهة برمجة التطبيقات للحقول
تسمح Fields API للجهة المحظورة بتعريف سمات الحساب للطلب من موفِّر الهوية كي يتمكّن المتصفّح من عرض واجهة مستخدم مناسبة للإفصاح في مربّع حوار FedCM، وتقع على عاتق موفِّر الهوية مسؤولية تضمين الحقول المطلوبة في الرمز المميّز الذي تم عرضه. ضع في اعتبارك أن هذا يطلب "ملفًا شخصيًا أساسيًا" في OpenID Connect مقابل "النطاقات" في OAuth.
![رسالة الإفصاح في وضع التطبيق المصغّر](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/blog/fedcm-126-with-disclosure-widget.jpg?authuser=3&hl=ar)
![رسالة الإفصاح في وضع الزر](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/blog/fedcm-126-with-disclosure-button.jpg?authuser=3&hl=ar)
لاستخدام 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
إذا كان الجهة المحظورة بحاجة إلى الوصول إلى أي بيانات إضافية من موفِّر الهوية، مثل الوصول إلى تقويم، يجب التعامل مع ذلك باستخدام مَعلمة مخصَّصة كما هو مذكور أعلاه. يعرض
موفِّر الهوية عنوان URL الخاص بالسمة continue_on
لطلب الإذن.
إذا كانت 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
مصفوفة فارغة، سيتخطّى وكيل المستخدم واجهة مستخدم الإفصاح.
![لا تظهر رسالة الإفصاح في وضع التطبيق المصغّر. وفي مسار الزر، يتم تخطّي واجهة المستخدم الخاصة ببيان الإفصاح بالكامل.](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/blog/fedcm-126-without-disclosure-widget.jpg?authuser=3&hl=ar)
ويحدث ذلك حتى إذا كان الردّ من نقطة نهاية
الحسابات لا يحتوي على معرِّف عميل يتطابق مع الجهة المحظورة في 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
تطبيقها حتى تصبح متوافقة مع الأنظمة القديمة.
يمكن أن يظهر الملف المعروف الذي يدعم عناوين configURL المتعددة على النحو التالي:
{
"provider_urls": [ "https://idp.example/fedcm.json" ],
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
ويسمح لنا ذلك بما يلي:
- الحفاظ على التوافق مع الملفات السابقة والمستقبلية مع الملفات المعروفة الحالية والإصدار السابق من المتصفحات التي تم نشرها فعلاً.
- تحتوي على عدد عشوائي من ملفات الإعداد، طالما أنّ جميعها تشير إلى
سمتَي
accounts_endpoint
وlogin_url
نفسيهما. - لا تكون لديك فرصة لإضافة القصور إلى طلب الجلب بيانات الاعتماد الذي تم إجراؤه على
accounts_endpoint
، لأنّه يجب تحديده على مستوى "well-known".
يُرجى العلم أنّ إتاحة عدة عناوين URL للإعداد هي إجراء اختياري، ويمكن أن تظلّ عمليات تنفيذ "المراسلة عبر السحابة الإلكترونية من Firebase" الحالية كما هي.
تصنيفات الحساب المخصّصة
تسمح تصنيفات الحسابات المخصّصة لموفِّري خدمة FedCM
بإضافة تعليقات توضيحية إلى الحسابات حتى يتمكّن الجهات المحظورة من فلترتها من خلال تحديد التصنيف في
ملف إعداد. توفّرت إمكانية إجراء فلترة مشابهة باستخدام واجهة برمجة تطبيقات "معلومات النطاق" وواجهة برمجة تطبيقات "معلومات تسجيل الدخول" من خلال تحديدهما في طلب "navigator.credentials.get()
"، إلا أنّ "تصنيفات الحساب المخصّص" يمكنها فلترة المستخدمين من خلال تحديد ملف الإعداد، وهو أمر مفيد بشكل خاص عند استخدام عناوين configURL متعددة. وتختلف أيضًا تصنيفات الحسابات المخصّصة في أنّها يتم توفيرها من خادم موفِّر الهوية (idP)، مقارنةً بتصنيفات الحسابات المخصّصة، مثل تلميحات تسجيل الدخول أو النطاق.
مثال
يتوافق موفِّر الهوية (idP) مع عنوانَي configURL للمستهلك والمؤسسات على التوالي. يحتوي ملف إعداد المستهلك على تصنيف 'consumer'
، ويحتوي ملف إعداد المؤسسة على تصنيف 'enterprise'
.
من خلال عملية الإعداد هذه، يشتمل الملف المعروف على 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
. ويمكن أن يشير الجهة المحظورة مباشرةً إلى ملفات الضبط
المعنية في استدعاء 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"
}
}
تعرض نقطة نهاية
حسابات موفِّر الهوية (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": ["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 كإشارة ثقة واجهة برمجة تطبيقات "الوصول إلى مساحة التخزين". من خلال هذا التغيير، يصبح منح الإذن المسبق من خلال FedCM سببًا وجيهًا للموافقة تلقائيًا على طلب الوصول إلى مساحة التخزين من خلال واجهات برمجة التطبيقات "الوصول إلى مساحة التخزين".
ويفيد ذلك عندما يريد إطار iframe مضمّن الوصول إلى موارد مخصّصة، على سبيل المثال، إذا كان idp.example مضمّنًا في rp.example ويحتاج إلى عرض مورد مخصّص. إذا كان المتصفّح يقيّد الوصول إلى ملفات تعريف الارتباط التابعة لجهات خارجية، حتى إذا سجَّل المستخدم الدخول إلى rp.example باستخدام idp.example مع FedCM، لن يتمكّن إطار iframe الذي تم تضمينه من خلال idp.example من طلب موارد مخصّصة لأن الطلبات لن تتضمّن ملفات تعريف الارتباط التابعة لجهات خارجية.
لتحقيق ذلك، يحتاج idp.example إلى الحصول على إذن الوصول إلى مساحة التخزين من خلال إطار iframe المضمّن في الموقع الإلكتروني، ولا يمكن الحصول على ذلك إلا من خلال طلب الإذن.
باستخدام 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
على الإصدار 126 من Chrome أو إصدار أحدث.
تتوفّر هذه الميزات أيضًا في مرحلة التجربة والتقييم. تتيح لك مراحل التجربة والتقييم تجربة ميزات جديدة وتقديم ملاحظات حول سهولة استخدامها وتطبيقها العملي وفعاليتها. لمزيد من المعلومات، يُرجى الاطّلاع على مقالة بدء استخدام مراحل التجربة والتقييم.
لتجربة الأصل التجريبي لحزمة واجهة برمجة التطبيقات Continuation API في FedCM، يمكنك إنشاء رمزين مميزين لمراحل التجربة والتقييم:
- يُرجى التسجيل في الفترة التجريبية. تضمين الرمز المميّز إلى مصدر موفِّر الهوية (idP)
- يمكنك التسجيل في مرحلة التجربة والتقييم من خلال وضع علامة في مربّع اختيار مطابقة جهة خارجية. اتّبِع التعليمات الواردة في مقالة تسجيل مرحلة تجريبية للمصدر التابع لجهة خارجية للجهة المحظورة من أجل تضمين الرمز المميّز الخاص بالجهة المحظورة.
إذا كنت مهتمًا بتفعيل Continuation API مع تدفق الزر، يمكنك أيضًا تفعيل التجربة الأصلية لواجهة برمجة التطبيقات Button Mode (وضع الزر) أيضًا:
- يمكنك التسجيل في مرحلة التجربة والتقييم كجهة خارجية. اتّبِع التعليمات الواردة في مقالة تسجيل فترة تجريبية للمصدر تابع لجهة خارجية في الجهة المحظورة بهدف تضمين الرمز المميّز الخاص بالجهة المحظورة.
لتجربة بروتوكول FedCM كإشارة ثقة في مرحلة التجربة والتقييم على Storage Access API:
- يُرجى التسجيل في مرحلة التجربة والتقييم. تضمين الرمز المميّز إلى مصدر موفِّر الهوية (idP)
من الإصدار Chrome 126، تتوفّر مرحلة التجربة والتقييم في حزمة Continuation API وFedCM كإشارة ثقة في مرحلة التجربة والتقييم في Storage Access API.
تسجيل مرحلة تجريبية للمصدر التابع لجهة خارجية في الجهة المحظورة
- انتقِل إلى صفحة التسجيل في مرحلة التجربة والتقييم.
- انقر على الزر تسجيل واملأ النموذج لطلب رمز مميّز.
- أدخِل مصدر موفِّر الهوية على أنّه مصدر الويب.
- تحقَّق من مطابقة الجهات الخارجية لإدخال الرمز المميّز مع JavaScript على مصادر أخرى.
- انقر على إرسال.
- تضمين الرمز المميّز الذي تم إصداره على موقع إلكتروني تابع لجهة خارجية
لتضمين الرمز المميّز على موقع إلكتروني تابع لجهة خارجية، أضِف الرمز التالي إلى مكتبة JavaScript أو حزمة تطوير البرامج (SDK) لموفِّر الهوية والمعروضة من مصدر موفِّر الهوية.
const tokenElement = document.createElement('meta');
tokenElement.httpEquiv = 'origin-trial';
tokenElement.content = 'TOKEN_GOES_HERE';
document.head.appendChild(tokenElement);
استبدِل TOKEN_GOES_HERE
بالرمز المميّز الخاص بك.