Apps de una sola página

Con IBM Cloud® App ID, puede añadir rápidamente autorización y autenticación a sus aplicaciones de una sola página (SPA). Una SPA se ejecuta en el navegador y no tiene un programa de fondo que gestiona el usuario; tampoco necesita que se vuelva a cargar la página mientras se utiliza la aplicación. Algunas infraestructuras comunes que se utilizan con SPA son Angular y React.

¿Tiene su app un programa de fondo que puede controlar? Quizás SPA no es el flujo que más le interesa. Pruebe el flujo de apps web.

Comprensión del flujo

Aunque es el estándar actual de la industria para SPA, el grupo de trabajo OAuth ya no recomienda el uso del flujo implícito debido a varios problemas de seguridad. Siguiendo su consejo, App ID está configurado para utilizar el flujo de Código de Autorización con PKCE.

Flujo de autorización
flujo de autorización de las
de una sola página*

  1. Un usuario intenta iniciar una sesión en la aplicación de una sola página.
  2. El SDK de App ID crea un verificador de código para la solicitud de autorización, que es la versión en texto sin formato de cambio de código. Junto con la solicitud de autorización, el cliente envía el cambio de código y el método de cambio que se utiliza para codificar el cambio.
  3. App ID inicia el flujo de autenticación en una ventana nueva.
  4. El usuario elige un proveedor de identidad para autenticarse con y completa el proceso de inicio de sesión.
  5. El SDK de App ID de la aplicación recibe el código de concesión
  6. A continuación, el SDK realiza una solicitud XHR al punto final de señal de App ID junto con el código de concesión y el verificador de código para obtener señales de acceso y de identidad.

¿Utiliza SSO para Cloud Directory? Puede utilizar el SDK de cliente de App ID para obtener automáticamente un nuevo par de señales sin que sea necesario que el usuario inicie sesión explícitamente. Para obtener más información, consulte Inicio de sesión silencioso.

¿Por qué Código + PKCE?

Debido a su naturaleza, las aplicaciones de una sola página no pueden almacenar secretos de forma segura. El flujo Autorización + PKCE, una variación del flujo de código de autorización OAuth 2.0, utiliza un verificador y un desafío de código de un solo uso en lugar de un secreto para abordar el problema. El verificador y el reto garantizan que la entidad que llama a los puntos finales de autorización y de señal sea la misma. Este proceso significa que un atacante no podría solicitar señales del servidor de autorizaciones sin conocer también el verificador de código.

Aunque el flujo implícito es el estándar actual del sector, se pueden encontrar varios defectos de seguridad. Por ejemplo, el flujo implícito utiliza los URI de redirección para obtener señales, que el flujo de tipo Autorización + PKCE elude utilizando en su lugar una solicitud XHR. Debido a los errores de seguridad, el flujo implícito ya no se recomienda ni se considera seguro debido a los siguientes motivos:

  • El flujo implícito devuelve señales como parte del URL, como un parámetro de consulta o en el fragmento hash. De este modo, se pueden interceptar las señales y se puede acceder a las señales. Las señales se pueden guardar en el historial del navegador de un usuario o en los registros. Es posible que el historial o los registros se almacenen en un servicio de nube y se envíen a varios dispositivos, lo que también aumenta el riesgo.

  • El flujo implícito es susceptible a un ataque de redirección URI, lo que significa que un atacante podría sustituir una URI de redirección aprobada por un destino de su elección. Si se produce un ataque de URI de redirección, los usuarios siguen el enlace modificado para autorizar a su cliente. Después de la autorización, se les redirige al URI de los atacantes, lo que otorga al atacante acceso a las señales legítimas del usuario.

Los ejemplos anteriores son solo algunos de los principales problemas. Para más información, consulte OAuth 2.0 security best current practice.

Antes de empezar

Antes de empezar, asegúrese de que dispone de los siguientes requisitos previos:

  • Una instancia del servicio App ID.
  • Los URI de redirección establecidos en el panel de control del servicio App ID.
  • Una aplicación de una sola página. Si no tiene una y desea probar el flujo, intente descargar la aplicación de ejemplo desde la página de visión general del panel de control de App ID.

Creación de credenciales de aplicación con la GUI

Las credenciales se utilizan para conectar la aplicación con App ID. Para crear sus credenciales, registre la app con App ID.

No se devuelve ningún secreto de cliente en las credenciales de SPA. No es necesario un secreto en el flujo de Autorización + PKCE. No puede utilizar las credenciales de app web normales en el flujo SPA.

  1. Regístrese en el panel de control de IBM Cloud de la región en la que desea trabajar.
  2. Vaya al separador Aplicaciones y pulse Añadir aplicación.
  3. Asigne un nombre a la aplicación.
  4. Seleccione Aplicación de una sola página en el menú desplegable Tipo.
  5. Pulse Guardar.
  6. En la tabla, pulse Ver credenciales para ver la información que se necesita en la configuración siguiente.

Creación de credenciales de aplicación con la API

Las credenciales se utilizan para conectar la aplicación con App ID. Para crear sus credenciales, registre la app con App ID.

No se devuelve ningún secreto de cliente en las credenciales de SPA. No es necesario un secreto en el flujo de Autorización + PKCE. No puede utilizar las credenciales de app web normales en el flujo SPA.

  1. Realice la siguiente solicitud de envío al /management/v4/Punto final de /aplicaciones.

    curl -X POST \
    https://us-south.appid.cloud.ibm.com/management/v4/<tenantID>/applications/ \
    -H 'accept: application/json' \
    -H 'Authorization: Bearer <IAMToken>' \
    -H 'Content-Type: application/json' \
    -d '{"name": "MySampleSPA", "type": "singlepageapp"}'
    

    Respuesta de ejemplo:

    {
       "clientId": "<clientID>",
       "tenantId": "<tenantID>",
       "name": "MySampleSPA",
       "oAuthServerUrl": "https://us-south.appid.cloud.ibm.com/oauth/v4/<tenantID>",
       "type": "singlepageapp"
    }
    

Configuración del SDK de JavaScript

Para instalar el SDK en la aplicación, siga los pasos siguientes como guía.

  1. En el indicador de mandatos, cambie al directorio que contiene la aplicación.

  2. Instale el servicio App ID mediante NPM o enlazando la CDN en su archivo HTML principal.

    • Para utilizar NPM, ejecute el siguiente mandato.

      npm install ibmcloud-appid-js
      
    • Para añadir la CDN, añada el siguiente enlace a su archivo HTML principal.

      <script src="https://cdn.appid.cloud.ibm.com/appid-0.3.0.min.js"></script>
      
  3. Añada el ID de cliente y el punto final de descubrimiento a la app para inicializar el SDK.

    const appID = new AppID();
    await appID.init({
       clientId: '<spaClientID>',
       discoveryEndpoint: '<wellKnownEndpoint>'
    });
    
  4. En el código de la aplicación, después de la configuración del botón de inicio de sesión, añada una llamada a signin. Se abre una ventana emergente en la que se solicita al usuario que especifique sus credenciales. Después de autenticarse correctamente, la pantalla se cierra y el usuario se autentica.

    const tokens = await appID.signin();
    

Configuración de un inicio de sesión silencioso

Cuando SSO for Cloud Directory está habilitado, puede obtener automáticamente nuevas señales para un usuario sin que tengan que volverse a autenticar mediante un inicio de sesión silencioso. Para habilitar el inicio de sesión silencioso, siga los pasos siguientes como guía.

Renueve las señales no se devuelven en el flujo SPA.

  1. En el panel de control de App ID, vaya a Cloud Directory > Inicio de sesión único.

  2. Cambie Habilitar inicio de sesión único a Habilitado.

  3. Pulse Guardar.

  4. Añada el código siguiente a la aplicación. Asegúrese de configurar la aplicación de modo que muestre el botón de inicio de sesión si el inicio de sesión silencioso falla.

    const tokens = await appID.silentSignin();
    if (!tokens) {
       document.getElementById('login').addEventListener('click', async () => {
       const tokens = await appID.signin();
       });
    }