Cómo integrar tu aplicación como iframe en B2CORE

Aprende a integrar una aplicación web de terceros en B2CORE como un iframe, incluida la configuración del servidor, la sincronización de tema e idioma y la autenticación basada en JWT mediante la API postMessage

B2CORE permite integrar aplicaciones web de terceros directamente en la interfaz de cliente mediante un iframe. Cuando se configura un elemento de menú personalizado con el comportamiento Iframe, B2CORE carga tu aplicación dentro de la interfaz, proporcionando una experiencia fluida para los clientes sin salir de la plataforma.

Esta guía cubre dos aspectos: la configuración del elemento de menú personalizado en el Back Office de B2CORE y la preparación de tu aplicación para funcionar correctamente dentro del iframe de B2CORE.

Requisitos previos

Antes de continuar, asegúrate de lo siguiente:

Paso 1. Configura tu servidor para permitir la integración mediante iframe

De forma predeterminada, la mayoría de los servidores web y frameworks impiden que las páginas se integren en iframes de otros dominios. Para permitir que B2CORE cargue tu aplicación, debes configurar los encabezados de respuesta HTTP adecuados en tu servidor.

Debes establecer uno o ambos de los siguientes encabezados:

Content-Security-Policy

El encabezado Content-Security-Policy con la directiva frame-ancestors controla qué orígenes pueden integrar tu página. Configura este encabezado para incluir el origen de tu instancia de B2CORE:

Content-Security-Policy: frame-ancestors 'self' https://portal.example.com

Reemplaza https://portal.example.com por el origen real de la interfaz de B2CORE utilizada por tus clientes. Puedes especificar varios orígenes separados por espacios si tu aplicación debe integrarse en varias instancias de B2CORE.

Para obtener más información, consulta la documentación de Content-Security-Policy en MDN.

X-Frame-Options

El encabezado X-Frame-Options es un mecanismo más antiguo que logra un resultado similar. Si lo utilizas, configúralo como ALLOW-FROM con el origen de tu B2CORE:

X-Frame-Options: ALLOW-FROM https://portal.example.com

La directiva X-Frame-Options: ALLOW-FROM no es compatible con todos los navegadores. Se recomienda utilizar el encabezado Content-Security-Policy con la directiva frame-ancestors como mecanismo principal e incluir X-Frame-Options solo como alternativa para clientes antiguos.

Para obtener más información, consulta la documentación de X-Frame-Options en MDN.

Paso 2. Añade un elemento de menú personalizado en el Back Office de B2CORE

Para que tu aplicación sea accesible para los clientes, añade un elemento de menú personalizado con el comportamiento iframe:

Ve a Promotion > Menu.

Haz clic en el icono de ojo de la fila General para ver el árbol de menús.

Haz clic en +Create en la esquina superior derecha de la página.

Completa los campos obligatorios:

  • En el campo Name, introduce un nombre único para el elemento de menú.
  • En el campo Caption, introduce la etiqueta que los clientes verán en el menú.
  • En el campo External URL, especifica la URL de tu aplicación.
  • En el campo Icon, especifica la URL de un icono SVG (16x16 px, monocromo, fondo transparente).
  • En el menú desplegable Custom Behavior, selecciona Iframe.

Configura restricciones opcionales si es necesario:

  • Para limitar la visibilidad a niveles de verificación específicos, selecciona los niveles adecuados en el menú desplegable Verification Level Allowance.
  • Para limitar la visibilidad a tipos de cliente específicos, selecciona los tipos correspondientes en el menú desplegable Client Type Allowance.

Activa la casilla Visible para que el elemento aparezca en el menú.

Haz clic en Save para añadir el elemento de menú personalizado.

Cuando los clientes hagan clic en este elemento de menú, tu aplicación se cargará dentro de un iframe en la interfaz de B2CORE.

Hay otras dos opciones de comportamiento disponibles para los elementos de menú personalizados: Same tab (abre la URL en la pestaña actual del navegador) y New tab (abre la URL en una nueva pestaña del navegador). La opción de iframe es la única que integra tu aplicación en la interfaz de B2CORE.

Paso 3 (opcional). Implementa el protocolo de comunicación postMessage

Si tu aplicación necesita identificar al usuario autenticado de B2CORE, coincidir con el tema de la interfaz de B2CORE o seguir el idioma seleccionado por el usuario, puedes implementar el protocolo de comunicación postMessage que se describe a continuación. Este paso es opcional: si tu aplicación no requiere autenticación de usuario, sincronización de tema ni sincronización de idioma, puedes omitirlo.

Referencia de mensajes

Mensajes de tu aplicación a B2CORE

Tipo de mensajeDescripciónCarga útil
embed-iframe-readyIndica que el iframe se ha cargado y está listo para recibir mensajes.{ type: "embed-iframe-ready" }
embed-request-jwt-tokenSolicita un token de autenticación JWT a B2CORE.{ type: "embed-request-jwt-token" }

Mensajes de B2CORE a tu aplicación

Tipo de mensajeDescripciónCarga útil
embed-theme-changeSe envía cada vez que cambia el tema de la interfaz de B2CORE (y una vez inmediatamente después de embed-iframe-ready).{ type: "embed-theme-change", theme: "dark-theme" | "light-theme" }
embed-language-changeSe envía cada vez que cambia el idioma de la interfaz de B2CORE (y una vez inmediatamente después de embed-iframe-ready).{ type: "embed-language-change", lang: "<language-code>" }
embed-jwt-tokenRespuesta correcta a una solicitud de token.{ type: "embed-jwt-token", token: "<jwt-string>", expiresAt: "<ISO-8601>" }
embed-jwt-token-errorRespuesta de error cuando falla la generación del token.{ type: "embed-jwt-token-error", error: "<error-message>" }
embed-logoutSe envía cuando el usuario de B2CORE cierra sesión. Cualquier token emitido anteriormente para tu aplicación ya no es válido.{ type: "embed-logout" }

El campo lang contiene un código de idioma ISO 639-1 en minúsculas (por ejemplo, en, de, ar) que coincide con el idioma seleccionado actualmente en la interfaz de B2CORE.

Un token JWT emitido mediante embed-jwt-token está vinculado al usuario de B2CORE que había iniciado sesión en el momento de su emisión. Cuando ese usuario cierra sesión, B2CORE envía embed-logout y el token ya no debe utilizarse. Descarta cualquier token almacenado en caché, detén las renovaciones programadas y borra el estado específico del usuario al recibir este mensaje. Si después inicia sesión otro usuario, solicita un nuevo token con embed-request-jwt-token: se emite un token nuevo para el nuevo usuario.

Flujo de comunicación

La secuencia de mensajes entre tu aplicación y B2CORE sigue este patrón:

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

Indica que estás listo. Cuando tu página termine de cargarse, envía el mensaje embed-iframe-ready a B2CORE. Esto informa al host de que tu aplicación está lista para recibir datos.

Recibe el tema actual. B2CORE responde con embed-theme-change, que contiene el tema actual (dark-theme o light-theme). Aplica el tema a tu interfaz. También recibirás este mensaje cada vez que el usuario cambie de tema.

Recibe el idioma actual. B2CORE también responde con embed-language-change, que contiene el código de idioma seleccionado actualmente en la interfaz de B2CORE (por ejemplo, en o ar). Aplica la configuración regional correspondiente a tu interfaz. Recibirás este mensaje nuevamente cada vez que el usuario cambie el idioma.

Solicita un token de autenticación. Cuando necesites identificar al usuario actual, envía embed-request-jwt-token. B2CORE responde con embed-jwt-token (que contiene el JWT y su hora de expiración) o con embed-jwt-token-error si falla la generación del token.

Renueva el token antes de que expire. El JWT tiene una hora de expiración proporcionada en el campo expiresAt (formato ISO 8601). Solicita un nuevo token antes de que expire el actual para mantener un acceso ininterrumpido.

Gestiona el cierre de sesión. Cuando el usuario de B2CORE cierra sesión, B2CORE envía embed-logout. Al recibirlo, descarta el token almacenado en caché, cancela cualquier renovación programada y borra el estado específico del usuario para que no se filtren datos al siguiente usuario. Si otro usuario inicia sesión posteriormente, solicita un token nuevo con embed-request-jwt-token.

Ejemplo de código

Un fragmento completo de JavaScript que puedes incluir en tu aplicación:

(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();
})();

Reemplaza el valor de B2CORE_ORIGIN por el origen real de tu instancia de B2CORE (por ejemplo, 'https://portal.example.com') en producción. El uso de '*' solo es aceptable durante el desarrollo, ya que permite que cualquier origen se comunique con tu aplicación.

Definiciones de tipos de TypeScript

Si tu aplicación está desarrollada con TypeScript, puedes utilizar las siguientes definiciones de tipos:

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;

Paso 4 (opcional). Valida el token JWT

El token JWT emitido por B2CORE se puede validar mediante el endpoint JSON Web Key Set (JWKS) expuesto por la API de B2CORE (backend del Panel de administración). Normalmente, este es el dominio de API/administración, no el dominio de la interfaz orientada al cliente:

https://api.<your-domain>/.well-known/jwks.json

Utiliza este endpoint para recuperar las claves públicas necesarias para verificar la firma del token. La mayoría de las bibliotecas JWT admiten la validación basada en JWKS de forma nativa.

Para la inspección manual durante el desarrollo, puedes decodificar y verificar tokens JWT con la herramienta de decodificación JWT.

Última actualización

En esta página