Compartir a través de


Autenticación para funciones personalizadas sin un entorno de ejecución compartido

En algunos escenarios, una función personalizada que no use un entorno de ejecución compartido tendrá que autenticar al usuario para acceder a los recursos protegidos. Funciones personalizadas que no usan una ejecución en tiempo de ejecución compartida en un entorno de ejecución solo de JavaScript. Por este motivo, si el complemento tiene un panel de tareas, deberá pasar datos entre el entorno de ejecución de solo JavaScript y el entorno de ejecución compatible con HTML que usa el panel de tareas. Para ello, use el objeto OfficeRuntime.storage y una API de diálogo especial.

Importante

Tenga en cuenta que las funciones personalizadas están disponibles en Excel en las siguientes plataformas.

  • Office en la web
  • Office en Windows
    • Suscripción a Microsoft 365
    • Retail perpetual Office 2016 y versiones posteriores
    • Licencia por volumen perpetua de Office 2021 y versiones posteriores
  • Office en Mac

Las funciones personalizadas de Excel no se admiten actualmente en lo siguiente:

  • Office en iPad
  • versiones perpetuas con licencia por volumen de Office 2019 o versiones anteriores en Windows

Nota:

Se recomienda usar funciones personalizadas con un entorno de ejecución compartido, a menos que tenga una razón específica para no usar un entorno de ejecución compartido. Tenga en cuenta que el uso de un entorno de ejecución compartido significa que el complemento usará WebView2 (basado en Microsoft Edge Chromium) si se cumplen las condiciones y, de lo contrario, el complemento usará Trident (Internet Explorer 11), independientemente de la versión de Windows o Microsoft 365. Para obtener una descripción de las condiciones de WebView2, vea Exploradores y controles de vista web que usan los complementos de Office. Para obtener más información sobre los tiempos de ejecución, vea Runtimes in Office Add-ins.

Objeto OfficeRuntime.storage

El entorno de ejecución solo JavaScript no tiene un localStorage objeto disponible en la ventana global, donde normalmente se almacenan datos. En su lugar, el código debe compartir datos entre funciones personalizadas y paneles de tareas mediante OfficeRuntime.storage para establecer y obtener datos.

Uso sugerido

Cuando necesite autenticarse desde un complemento de función personalizada que no use un entorno de ejecución compartido, el código debe comprobar OfficeRuntime.storage si el token de acceso ya se ha adquirido. Si no es así, use OfficeRuntime.displayWebDialog para autenticar al usuario, recuperar el token de acceso y, a continuación, almacenar el token en OfficeRuntime.storage para su uso futuro.

API de diálogo

Si no existe un token, debe usar la OfficeRuntime.dialog API para pedir al usuario que inicie sesión. Una vez que un usuario escribe sus credenciales, el token de acceso resultante se puede almacenar como un elemento en OfficeRuntime.storage.

Nota:

El tiempo de ejecución de solo JavaScript usa un objeto de diálogo ligeramente diferente del objeto dialog en el tiempo de ejecución del explorador utilizado por los paneles de tareas. Ambos se conocen como "DIALOG API", pero usan OfficeRuntime.displayWebDialog para autenticar a los usuarios en el entorno de ejecución de solo JavaScript, noOffice.ui.displayDialogAsync.

El siguiente diagrama resume este proceso básico. La línea de puntos indica que las funciones personalizadas y el panel de tareas del complemento forman parte del complemento en su conjunto, aunque usan tiempos de ejecución independientes.

  1. Se emite una llamada de función personalizada desde una celda de un libro de Excel.
  2. La función personalizada usa OfficeRuntime.dialog para pasar las credenciales de usuario a un sitio web.
  3. A continuación, este sitio web devuelve un token de acceso a la página del cuadro de diálogo.
  4. JavaScript en el cuadro de diálogo llama a la función Office.ui.messageParent para enviar el token de acceso a la función personalizada. Para obtener más información sobre esta función, vea Enviar información desde el cuadro de diálogo a la página host.
  5. A continuación, la función personalizada establece este token de acceso en un elemento de OfficeRuntime.storage.
  6. El panel de tareas del complemento obtiene acceso al token desde OfficeRuntime.storage.

Diagrama de la función personalizada mediante la API de cuadro de diálogo para obtener el token de acceso y, a continuación, compartir el token con el panel de tareas a través de la API OfficeRuntime.storage.

Almacenar el token

Los ejemplos siguientes provienen del código de ejemplo en Using OfficeRuntime.storage in custom functions. Consulte este ejemplo de código para obtener un ejemplo completo de uso compartido de datos entre funciones personalizadas y el panel de tareas en complementos que no usan un entorno de ejecución compartido.

Si la función personalizada se autentica, entonces recibe el token de acceso y tendrá que almacenarlo en OfficeRuntime.storage. El siguiente código de ejemplo muestra cómo llamar al método storage.setItem para almacenar un valor. La storeValue función es una función personalizada que almacena un valor del usuario. Puede modificar esto para almacenar cualquier valor de token que necesite.

/**
 * Stores a key-value pair into OfficeRuntime.storage.
 * @customfunction
 * @param {string} key Key of item to put into storage.
 * @param {*} value Value of item to put into storage.
 */
function storeValue(key, value) {
  return OfficeRuntime.storage.setItem(key, value).then(function (result) {
      return "Success: Item with key '" + key + "' saved to storage.";
  }, function (error) {
      return "Error: Unable to save item with key '" + key + "' to storage. " + error;
  });
}

Cuando el panel de tareas necesita el token de acceso, puede recuperar el token del OfficeRuntime.storage elemento. El siguiente código de ejemplo muestra cómo llamar al método storage.getItem para recuperar el token.

/**
 * Read a token from storage.
 * @customfunction GETTOKEN
 */
function receiveTokenFromCustomFunction() {
  const key = "token";
  const tokenSendStatus = document.getElementById('tokenSendStatus');
  OfficeRuntime.storage.getItem(key).then(function (result) {
     tokenSendStatus.value = "Success: Item with key '" + key + "' read from storage.";
     document.getElementById('tokenTextBox2').value = result;
  }, function (error) {
     tokenSendStatus.value = "Error: Unable to read item with key '" + key + "' from storage. " + error;
  });
}

Instrucciones generales

Los complementos de Office se basan en la web y puede usar cualquier técnica de autenticación web. No hay ningún patrón o método concreto que deba seguir para implementar su propia autenticación con funciones personalizadas. Le recomendamos consultar la documentación sobre los distintos patrones de autenticación, comenzando con este artículo sobre la autorización a través de servicios externos.

Evite usar las siguientes ubicaciones para almacenar datos al desarrollar funciones personalizadas:

  • localStorage: las funciones personalizadas que no usan un entorno de ejecución compartido no tienen acceso al objeto global window y, por tanto, no tienen acceso a los datos almacenados en localStorage.
  • Office.context.document.settings: esta ubicación no es segura y cualquiera que use el complemento puede extraer información.

Ejemplo de API de cuadro de diálogo

En el ejemplo de código siguiente, la función getTokenViaDialog usa la OfficeRuntime.displayWebDialog función para mostrar un cuadro de diálogo. Este ejemplo se proporciona para mostrar las funcionalidades del método, no para demostrar cómo autenticarse.

/**
 * Function retrieves a cached token or opens a dialog box if there is no saved token. Note that this isn't a sufficient example of authentication but is intended to show the capabilities of the displayWebDialog method.
 * @param {string} url URL for a stored token.
 */
function getTokenViaDialog(url) {
  return new Promise (function (resolve, reject) {
    if (_dialogOpen) {
      // Can only have one dialog box open at once. Wait for previous dialog box's token.
      let timeout = 5;
      let count = 0;
      const intervalId = setInterval(function () {
        count++;
        if(_cachedToken) {
          resolve(_cachedToken);
          clearInterval(intervalId);
        }
        if(count >= timeout) {
          reject("Timeout while waiting for token");
          clearInterval(intervalId);
        }
      }, 1000);
    } else {
      _dialogOpen = true;
      OfficeRuntime.displayWebDialog(url, {
        height: '50%',
        width: '50%',
        onMessage: function (message, dialog) {
          _cachedToken = message;
          resolve(message);
          dialog.close();
          return;
        },
        onRuntimeError: function(error, dialog) {
          reject(error);
        },
      }).catch(function (e) {
        reject(e);
      });
    }
  });
}

Siguientes pasos

Obtenga información sobre cómo depurar funciones personalizadas.

Vea también