بدءًا من Chrome 126، يمكن للمطوِّرين البدء في تنفيذ فترة تجريبية للمصدر لحزمة من ميزات واجهة برمجة التطبيقات Federated Credential Management API (FedCM) التي تتيح بعض حالات استخدام التفويض: تتكوّن الحزمة من Continuation API واجهة برمجة التطبيقات للمعلَمات التي تتيح تجربة مماثلة لتدفق تفويض 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');
واجهة برمجة التطبيقات للمعلَمات
تسمح واجهة برمجة التطبيقات للمعلَمات بالجهة المحظورة. لتوفير معلَمات إضافية في تأكيد المعرّف النهائية. باستخدام واجهة برمجة التطبيقات Integrations، يمكن للجهات المحظورة تمرير مَعلمات إضافية إلى موفِّر الهوية من أجل طلب أذونات لموارد تتجاوز تسجيل الدخول الأساسي. يسمح المستخدم هذه الأذونات من خلال تدفق تجربة مستخدم يتحكم فيه موفِّر الهوية (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()
من خلال إدخال المَعلمات المطلوبة التي يمكن لموفِّر الهوية (idP) الوصول إليها. الفهم، مثلscope
. - تأكيد المعرّف
نقطة نهاية
يؤكد أن المستخدم قد سجل الدخول من قبل ويستجيب باستخدام عنوان URL
continue_on
. - يفتح المتصفِّح نافذة منبثقة تعرض صفحة إذن موفِّر الهوية (idP) التي تطلب إدخال إذن إضافي يتطابق مع النطاقات المطلوبة.
- بعد أن يفوّض موفِّر الهوية (idP) الإذن من خلال
IdentityProvider.resolve()
، تصبح النافذة إغلاق وتلقى مكالمةnavigator.credentials.get()
الأصلية للجهة المحظورة أو رمز تفويض ذي صلة بحيث يمكن للجهة المحظورة استبداله رمز الدخول المناسب.
واجهة برمجة التطبيقات للحقول
تسمح Fields API للجهة المحظورة بما يلي: الإفصاح عن سمات الحساب للطلب من موفِّر الهوية (idP) حتى يتمكّن المتصفِّح عرض واجهة مستخدم مناسبة للإفصاح في مربّع حوار "المراسلة عبر السحابة الإلكترونية من Firebase" تقع على عاتق موفِّر الهوية مسؤولية لتضمين الحقول المطلوبة في الرمز المميز الذي تم إرجاعه. يمكنك تقديم هذا الطلب "ملف شخصي أساسي" في OpenID Connect مقابل "النطاقات" في بروتوكول OAuth.
![رسالة الإفصاح في وضع التطبيق المصغّر](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/blog/fedcm-126-with-disclosure-widget.jpg?authuser=19&hl=ar)
![رسالة الإفصاح في وضع الزر](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/blog/fedcm-126-with-disclosure-button.jpg?authuser=19&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=19&hl=ar)
ينطبق ذلك حتى إذا كان الردّ من الحسابات
نقطة نهاية
لا يحتوي على معرّف عميل يتطابق مع الجهة المحظورة في approved_clients
.
في هذه الحالة، تمّ إرسال disclosure_text_shown
إلى تأكيد المعرّف.
نقطة النهاية هي
false في نص 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 للإعداد هي إجراء اختياري، ويمكن استخدام بروتوكول FedCM الحالي. عمليات التنفيذ كما هي.
تصنيفات الحساب المخصّصة
تسمح تصنيفات الحسابات المخصّصة بخدمة FedCM
بإمكان موفِّري الهوية إضافة تعليقات توضيحية إلى الحسابات بحيث يمكن للجهات المحظورة فلترتها من خلال تحديد التصنيف
ملف تهيئة. تم إجراء تصفية مشابهة باستخدام تلميح النطاق
واجهة برمجة التطبيقات وتسجيل الدخول
Hint API من خلال تحديد
في المكالمة navigator.credentials.get()
، ولكن تصنيفات الحساب المخصصة
تصفية المستخدمين من خلال تحديد ملف التهيئة، وهو أمر مفيد بشكل خاص عندما
يتم استخدام العديد من configURLs. تصنيفات الحساب المخصّصة هي
تختلف أيضًا في أنها تتوفر من خادم موفر الهوية (idP)، بدلاً من
الجهة المحظورة، مثل تسجيل الدخول أو تلميحات النطاق.
مثال
يتوافق موفِّر الهوية (idP) مع عنوانَي configURL للمستهلك والمؤسسات على التوالي. تشير رسالة الأشكال البيانية
يحتوي ملف إعداد المستهلك على تصنيف 'consumer'
، وملف إعداد المؤسسة.
يتضمّن التصنيف 'enterprise'
.
باستخدام هذا الإعداد، يشتمل الملف المعروف على accounts_endpoint
login_url
للسماح بإعدادات عناوين URL متعددة.
{
"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'
لكي يتمكّن المستخدم.
لن يتم توفيره مع حساب غير متوافق مع موفِّر الهوية على هذا الموقع الإلكتروني.
مرحلة التجربة والتقييم: FedCM كإشارة ثقة لواجهة Storage Access API
يبدأ Chrome 126 مرحلة تجريبية في الأصل من FedCM كإشارة ثقة الوصول إلى مساحة التخزين API. مع بهذا التغيير، يصبح منح الإذن المسبق من خلال FedCM سببًا وجيهًا الموافقة تلقائيًا على طلب الوصول إلى مساحة التخزين عن طريق الوصول إلى مساحة التخزين API.
يفيد ذلك عندما يريد إطار iframe مضمن الوصول إلى موارد مخصصة: على سبيل المثال، إذا تم تضمين idp.example في rp.example وتحتاج إلى عرض المخصص. في حال حظر المتصفّح الوصول إلى ملفات تعريف الارتباط التابعة لجهات خارجية حتى إذا سجّل المستخدم الدخول إلى rp.example باستخدام idp.example مع FedCM، لن يتمكن إطار iframe المضمن idp.example من طلب موارد مخصصة لأنّ الطلبات لن تتضمّن ملفات تعريف الارتباط التابعة لجهات خارجية
لتحقيق ذلك، يحتاج idp.example إلى الحصول على إذن الوصول إلى مساحة التخزين من خلال iframe مضمن في موقع الويب، ولا يمكن الحصول على ذلك إلا من خلال طلب الحصول على إذن
استخدام FedCM كإشارة ثقة للوصول إلى مساحة التخزين API، إنّ عمليات التحقّق من إذن واجهة برمجة التطبيقات Storage Access لا تقبل فقط منح الإذن الذي من خلال طلب الوصول إلى مساحة التخزين، وأيضًا من خلال منح الإذن الذي يمنحه طلب 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 إلى جانب الزر التدفق، فعِّل وضع الزر مصدر واجهة برمجة التطبيقات فترة تجريبية كذلك:
- يمكنك التسجيل في مرحلة التجربة والتقييم كجهة خارجية. اتّبِع التعليمات الواردة في تسجيل مرحلة تجريبية للمصدر التابع لجهة خارجية في الجهة المحظورة لتضمينها الرمز المميز للجهة المحظورة.
لتجربة بروتوكول FedCM كإشارة ثقة لمصدر واجهة برمجة التطبيقات Storage Access API الفترة التجريبية:
- يُرجى التسجيل في مرحلة التجربة والتقييم. تضمين الرمز المميّز لموفِّر الهوية (idP) الأصل.
مرحلة التجربة والتقييم لحزمة Continuation API وFedCM كإشارة ثقة تتوفر مرحلة التجربة والتقييم على "واجهة برمجة التطبيقات للوصول إلى مساحة التخزين" من Chrome 126.
تسجيل مرحلة تجريبية للمصدر التابع لجهة خارجية في الجهة المحظورة
- انتقِل إلى صفحة التسجيل في مرحلة التجربة والتقييم.
- انقر على الزر تسجيل واملأ النموذج لطلب رمز مميّز.
- أدخِل مصدر موفِّر الهوية على أنّه مصدر الويب.
- تحقَّق من مطابقة الجهات الخارجية لإدخال الرمز المميّز مع JavaScript على مصادر أخرى.
- انقر على إرسال.
- تضمين الرمز المميّز الذي تم إصداره على موقع إلكتروني تابع لجهة خارجية
لتضمين الرمز المميّز على موقع إلكتروني تابع لجهة خارجية، أضِف الرمز التالي إلى موفِّر الهوية مكتبة JavaScript أو حزمة تطوير البرامج (SDK) المعروضة من مصدر موفِّر الهوية (idP).
const tokenElement = document.createElement('meta');
tokenElement.httpEquiv = 'origin-trial';
tokenElement.content = 'TOKEN_GOES_HERE';
document.head.appendChild(tokenElement);
استبدِل TOKEN_GOES_HERE
بالرمز المميّز الخاص بك.