كيفية دمج تطبيقك كإطار iframe في B2CORE
تعرّف على كيفية دمج تطبيق ويب تابع لجهة خارجية في B2CORE كإطار iframe، بما في ذلك إعداد الخادم، ومزامنة النسق واللغة، والمصادقة المستندة إلى JWT عبر واجهة postMessage API
يدعم B2CORE تضمين تطبيقات الويب التابعة لجهات خارجية مباشرةً في واجهة المستخدم الخاصة بالعميل عبر إطار iframe. عند إعداد عنصر قائمة مخصص بسلوك Iframe، يقوم B2CORE بتحميل تطبيقك داخل الواجهة، مما يوفر تجربة سلسة للعملاء دون مغادرة المنصة.
يغطي هذا الدليل جانبين: إعداد عنصر القائمة المخصص في Back Office الخاص بـ B2CORE، وتجهيز تطبيقك للعمل بشكل صحيح داخل إطار iframe الخاص بـ B2CORE.
المتطلبات الأساسية
قبل المتابعة، تأكد مما يلي:
- يمكن الوصول إلى تطبيقك عبر HTTPS.
- لديك حق الوصول إلى Back Office الخاص بـ B2CORE مع إذن
Update menu(للتفاصيل، راجع كيفية إضافة مجموعة مستخدمين ومنح الأذونات). - أنت على دراية بإجراء كيفية إضافة عناصر قائمة مخصصة.
الخطوة 1. إعداد الخادم للسماح بالتضمين في إطار iframe
بشكل افتراضي، تمنع معظم خوادم الويب وأطر العمل تضمين الصفحات في إطارات iframe على نطاقات أخرى. للسماح لـ B2CORE بتحميل تطبيقك، يجب إعداد رؤوس استجابة HTTP المناسبة على خادمك.
تحتاج إلى تعيين رأس واحد أو كليهما من الرؤوس التالية:
Content-Security-Policy
يتحكم رأس Content-Security-Policy باستخدام التوجيه frame-ancestors في المصادر المسموح لها بتضمين صفحتك. عيّن هذا الرأس ليشمل مصدر مثيل B2CORE الخاص بك:
Content-Security-Policy: frame-ancestors 'self' https://portal.example.comاستبدل https://portal.example.com بالمصدر الفعلي لواجهة مستخدم B2CORE التي يستخدمها عملاؤك. يمكنك تحديد مصادر متعددة مفصولة بمسافات إذا كان تطبيقك يحتاج إلى التضمين عبر عدة مثيلات من B2CORE.
لمزيد من المعلومات، راجع وثائق Content-Security-Policy على MDN.
X-Frame-Options
رأس X-Frame-Options هو آلية أقدم تحقق نتيجة مشابهة. إذا كنت تستخدمه، فعيّنه على ALLOW-FROM مع مصدر B2CORE الخاص بك:
X-Frame-Options: ALLOW-FROM https://portal.example.comلا تدعم جميع المتصفحات توجيه X-Frame-Options: ALLOW-FROM. يُوصى باستخدام رأس Content-Security-Policy مع التوجيه frame-ancestors كآلية أساسية، وإضافة X-Frame-Options فقط كخيار احتياطي للعملاء الأقدم.
لمزيد من المعلومات، راجع وثائق X-Frame-Options على MDN.
الخطوة 2. إضافة عنصر قائمة مخصص في Back Office الخاص بـ B2CORE
لجعل تطبيقك متاحًا للعملاء، أضف عنصر قائمة مخصصًا بسلوك iframe:
انتقل إلى Promotion > Menu.
انقر على أيقونة العين في صف General لعرض شجرة القائمة.
انقر على +Create في الزاوية العلوية اليمنى من الصفحة.
املأ الحقول المطلوبة:
- في حقل Name، أدخل اسمًا فريدًا لعنصر القائمة.
- في حقل Caption، أدخل التسمية التي سيراها العملاء في القائمة.
- في حقل External URL، حدد عنوان URL لتطبيقك.
- في حقل Icon، حدد عنوان URL لأيقونة SVG (16x16 px، أحادية اللون، بخلفية شفافة).
- في القائمة المنسدلة Custom Behavior، حدد Iframe.
اضبط القيود الاختيارية عند الحاجة:
- لتقييد الظهور على مستويات تحقق محددة، حدد المستويات المناسبة في القائمة المنسدلة Verification Level Allowance.
- لتقييد الظهور على أنواع عملاء محددة، حدد الأنواع المقابلة في القائمة المنسدلة Client Type Allowance.
فعّل مربع الاختيار Visible لإظهار العنصر في القائمة.
انقر على Save لإضافة عنصر القائمة المخصص.
عندما ينقر العملاء على عنصر القائمة هذا، سيتم تحميل تطبيقك داخل إطار iframe ضمن واجهة مستخدم B2CORE.
يتوفر خياران آخران للسلوك لعناصر القائمة المخصصة: Same tab (يفتح عنوان URL في علامة تبويب المتصفح الحالية) وNew tab (يفتح عنوان URL في علامة تبويب متصفح جديدة). خيار iframe هو الخيار الوحيد الذي يضمّن تطبيقك داخل واجهة B2CORE.
الخطوة 3 (اختياري). تنفيذ بروتوكول اتصال postMessage
إذا كان تطبيقك يحتاج إلى تحديد مستخدم B2CORE المصادق عليه، أو مطابقة نسق واجهة مستخدم B2CORE، أو اتباع اللغة التي حددها المستخدم، فيمكنك تنفيذ بروتوكول اتصال postMessage الموضح أدناه. هذه الخطوة اختيارية — إذا كان تطبيقك لا يتطلب مصادقة المستخدم أو مزامنة النسق أو مزامنة اللغة، فيمكنك تخطيها.
مرجع الرسائل
الرسائل من تطبيقك إلى B2CORE
| نوع الرسالة | الوصف | الحمولة |
|---|---|---|
embed-iframe-ready | يشير إلى أن إطار iframe تم تحميله وجاهز لتلقي الرسائل. | { type: "embed-iframe-ready" } |
embed-request-jwt-token | يطلب رمز مصادقة JWT من B2CORE. | { type: "embed-request-jwt-token" } |
الرسائل من B2CORE إلى تطبيقك
| نوع الرسالة | الوصف | الحمولة |
|---|---|---|
embed-theme-change | تُرسل كلما تغير نسق واجهة مستخدم B2CORE (ومرة فورًا بعد embed-iframe-ready). | { type: "embed-theme-change", theme: "dark-theme" | "light-theme" } |
embed-language-change | تُرسل كلما تغيرت لغة واجهة مستخدم B2CORE (ومرة فورًا بعد embed-iframe-ready). | { type: "embed-language-change", lang: "<language-code>" } |
embed-jwt-token | استجابة ناجحة لطلب رمز مميز. | { type: "embed-jwt-token", token: "<jwt-string>", expiresAt: "<ISO-8601>" } |
embed-jwt-token-error | استجابة خطأ عند فشل إنشاء الرمز المميز. | { type: "embed-jwt-token-error", error: "<error-message>" } |
embed-logout | تُرسل عندما يسجل مستخدم B2CORE الخروج. يصبح أي رمز مميز صدر سابقًا لتطبيقك غير صالح. | { type: "embed-logout" } |
يحتوي الحقل lang على رمز لغة ISO 639-1 بأحرف صغيرة (على سبيل المثال، en أو de أو ar) يطابق اللغة المحددة حاليًا في واجهة مستخدم B2CORE.
يرتبط رمز JWT المميز الصادر عبر embed-jwt-token بمستخدم B2CORE الذي كان مسجل الدخول عند إصدار الرمز. عندما يسجل ذلك المستخدم الخروج، يرسل B2CORE الرسالة embed-logout ويجب عدم استخدام الرمز المميز بعد ذلك. تخلص من أي رمز مميز مخزن مؤقتًا، وأوقف عمليات التحديث المجدولة، وامسح الحالة الخاصة بالمستخدم عند تلقي هذه الرسالة. إذا سجل مستخدم مختلف الدخول بعد ذلك، فاطلب رمزًا مميزًا جديدًا باستخدام embed-request-jwt-token — سيتم إصدار رمز مميز جديد للمستخدم الجديد.
تدفق الاتصال
يتبع تسلسل الرسائل بين تطبيقك وB2CORE هذا النمط:
sequenceDiagram
participant App as Your App (iframe)
participant B2CORE as B2CORE (host)
App->>B2CORE: embed-iframe-ready
B2CORE-->>App: embed-theme-change (initial theme)
B2CORE-->>App: embed-language-change (initial language)
App->>B2CORE: embed-request-jwt-token
alt success
B2CORE-->>App: embed-jwt-token
else failure
B2CORE-->>App: embed-jwt-token-error
end
Note over App,B2CORE: Token nears expiry...
App->>B2CORE: embed-request-jwt-token
B2CORE-->>App: embed-jwt-token
Note over App,B2CORE: User toggles theme...
B2CORE-->>App: embed-theme-change
Note over App,B2CORE: User changes language...
B2CORE-->>App: embed-language-change
Note over App,B2CORE: User logs out...
B2CORE-->>App: embed-logoutالإشارة إلى الجاهزية. عند انتهاء تحميل صفحتك، أرسل رسالة embed-iframe-ready إلى B2CORE. يخبر هذا المضيف بأن تطبيقك جاهز لتلقي البيانات.
تلقي النسق الحالي. يستجيب B2CORE برسالة embed-theme-change التي تحتوي على النسق الحالي (dark-theme أو light-theme). طبّق النسق على واجهة المستخدم الخاصة بك. ستتلقى هذه الرسالة أيضًا كلما بدّل المستخدم النسق.
تلقي اللغة الحالية. يستجيب B2CORE أيضًا برسالة embed-language-change التي تحتوي على رمز اللغة المحدد حاليًا في واجهة مستخدم B2CORE (على سبيل المثال، en أو ar). طبّق اللغة المحلية المقابلة على واجهة المستخدم الخاصة بك. ستتلقى هذه الرسالة مجددًا كلما غيّر المستخدم اللغة.
طلب رمز مصادقة مميز. عندما تحتاج إلى تحديد المستخدم الحالي، أرسل embed-request-jwt-token. يستجيب B2CORE إما برسالة embed-jwt-token (تحتوي على JWT ووقت انتهاء صلاحيته) أو برسالة embed-jwt-token-error إذا فشل إنشاء الرمز المميز.
تحديث الرمز المميز قبل انتهاء الصلاحية. يحتوي JWT على وقت انتهاء صلاحية محدد في الحقل expiresAt (بتنسيق ISO 8601). اطلب رمزًا مميزًا جديدًا قبل انتهاء صلاحية الرمز الحالي للحفاظ على وصول دون انقطاع.
معالجة تسجيل الخروج. عندما يسجل مستخدم B2CORE الخروج، يرسل B2CORE الرسالة embed-logout. عند تلقيها، تخلص من الرمز المميز المخزن مؤقتًا، وألغِ أي تحديث مجدول، وامسح الحالة الخاصة بالمستخدم حتى لا تتسرب أي بيانات إلى المستخدم التالي. إذا سجل مستخدم آخر الدخول بعد ذلك، فاطلب رمزًا مميزًا جديدًا باستخدام embed-request-jwt-token.
مثال على التعليمات البرمجية
مقتطف JavaScript كامل يمكنك تضمينه في تطبيقك:
(function () {
const B2CORE_ORIGIN = '*'; // Replace with your B2CORE instance origin for production
let currentToken = null;
let tokenRefreshTimer = null;
// --- Send a message to B2CORE ---
function sendToHost(message) {
window.parent.postMessage(message, B2CORE_ORIGIN);
}
// --- Handle incoming messages from B2CORE ---
function handleMessage(event) {
const data = event.data;
if (!data || !data.type) return;
switch (data.type) {
case 'embed-theme-change':
applyTheme(data.theme);
break;
case 'embed-language-change':
applyLanguage(data.lang);
break;
case 'embed-jwt-token':
handleToken(data.token, data.expiresAt);
break;
case 'embed-jwt-token-error':
console.error('Token error from B2Core:', data.error);
break;
case 'embed-logout':
handleLogout();
break;
}
}
// --- Apply theme to your UI ---
function applyTheme(theme) {
document.documentElement.setAttribute('data-theme', theme);
}
// --- Apply language to your UI ---
function applyLanguage(lang) {
document.documentElement.setAttribute('lang', lang);
}
// --- Handle received JWT token ---
function handleToken(token, expiresAt) {
currentToken = token;
// Schedule a refresh 2 minutes before expiry
if (tokenRefreshTimer) {
clearTimeout(tokenRefreshTimer);
}
const refreshIn = new Date(expiresAt).getTime() - Date.now() - 2 * 60 * 1000;
if (refreshIn > 0) {
tokenRefreshTimer = setTimeout(requestToken, refreshIn);
} else {
requestToken();
}
}
// --- Request a JWT token from B2CORE ---
function requestToken() {
sendToHost({ type: 'embed-request-jwt-token' });
}
// --- Handle B2CORE user logout ---
function handleLogout() {
// The token is bound to the user who just logged out — stop using it.
currentToken = null;
if (tokenRefreshTimer) {
clearTimeout(tokenRefreshTimer);
tokenRefreshTimer = null;
}
// Clear any user-specific state in your app here.
}
// --- Initialize ---
window.addEventListener('message', handleMessage);
sendToHost({ type: 'embed-iframe-ready' });
requestToken();
})();استبدل قيمة B2CORE_ORIGIN بالمصدر الفعلي لمثيل B2CORE الخاص بك (على سبيل المثال، 'https://portal.example.com') في بيئة الإنتاج. لا يُقبل استخدام '*' إلا أثناء التطوير، لأنه يسمح لأي مصدر بالاتصال بتطبيقك.
تعريفات أنواع TypeScript
إذا كان تطبيقك مبنيًا باستخدام TypeScript، فيمكنك استخدام تعريفات الأنواع التالية:
type EmbedTheme = 'dark-theme' | 'light-theme';
// Messages: Your App -> B2CORE
interface EmbedIframeReadyMessage {
readonly type: 'embed-iframe-ready';
}
interface EmbedRequestJwtTokenMessage {
readonly type: 'embed-request-jwt-token';
}
type EmbedOutboundMessage = EmbedIframeReadyMessage | EmbedRequestJwtTokenMessage;
// Messages: B2CORE -> Your App
interface EmbedThemeChangeMessage {
readonly type: 'embed-theme-change';
readonly theme: EmbedTheme;
}
interface EmbedLanguageChangeMessage {
readonly type: 'embed-language-change';
readonly lang: string; // ISO 639-1 code, e.g. "en", "de", "ar"
}
interface EmbedJwtTokenMessage {
readonly type: 'embed-jwt-token';
readonly token: string;
readonly expiresAt: string; // ISO 8601
}
interface EmbedJwtTokenErrorMessage {
readonly type: 'embed-jwt-token-error';
readonly error: string;
}
interface EmbedLogoutMessage {
readonly type: 'embed-logout';
}
type EmbedInboundMessage =
| EmbedThemeChangeMessage
| EmbedLanguageChangeMessage
| EmbedJwtTokenMessage
| EmbedJwtTokenErrorMessage
| EmbedLogoutMessage;الخطوة 4 (اختياري). التحقق من رمز JWT المميز
يمكن التحقق من رمز JWT المميز الصادر عن B2CORE باستخدام نقطة نهاية JSON Web Key Set (JWKS) التي توفرها واجهة B2CORE API (الواجهة الخلفية للوحة الإدارة). يكون هذا عادةً نطاق API/admin، وليس نطاق واجهة المستخدم الموجهة للعملاء:
https://api.<your-domain>/.well-known/jwks.jsonاستخدم نقطة النهاية هذه لاسترداد المفاتيح العامة اللازمة للتحقق من توقيع الرمز المميز. تدعم معظم مكتبات JWT التحقق المستند إلى JWKS مباشرةً.
للفحص اليدوي أثناء التطوير، يمكنك فك ترميز رموز JWT المميزة والتحقق منها باستخدام أداة فك ترميز JWT.
آخر تحديث في