Gestionar sesiones de IAP

En esta página se describe cómo gestiona Identity-Aware Proxy (IAP) una solicitud con una sesión caducada y cómo asegurarse de que las solicitudes de aplicaciones AJAX y las solicitudes de WebSocket se completen correctamente.

Flujo de sesión de IAP

Cuando se usa el flujo de inicio de sesión estándar de IAP, el usuario recibe una cookie de sesión que hace referencia a su sesión de inicio de sesión de Google. IAP usa esta cookie para confirmar que el usuario sigue con la sesión iniciada. La compra en la aplicación requiere que un usuario inicie sesión antes de acceder a una aplicación protegida por IAP.

Las sesiones de compras en la aplicación se actualizan periódicamente. Sin embargo, si el usuario utiliza una cuenta de Google para iniciar sesión, las sesiones de compra en la aplicación también se vinculan a la sesión de inicio de sesión de Google del usuario. En este caso, la compra en la aplicación solo requerirá que el usuario vuelva a iniciar sesión en una de las siguientes situaciones:

  • El usuario ha cerrado sesión en su cuenta
  • Se ha suspendido su cuenta
  • La cuenta requiere que se restablezca la contraseña

Si se cierra la sesión de un usuario, IAP detecta un cambio en el estado de la cuenta de Google en un par de minutos. Una vez detectado, la compra en la aplicación invalida la sesión.

IAP vuelve a comprobar la autorización de Gestión de Identidades y Accesos (IAM) de todas las solicitudes durante las sesiones válidas. Los cambios en la política de acceso de gestión de identidades y accesos de una aplicación protegida por IAP pueden tardar unos minutos en aplicarse.

Vencimiento de la sesión de IAP

En un flujo de inicio de sesión con una cuenta de Google, la sesión de IAP está vinculada a la sesión de inicio de sesión de Google subyacente y solo caduca cuando caduca esa sesión, independientemente de la reclamación exp del JWT enviado en el encabezado de autorización.

En el caso de la autenticación programática, IAP respeta la reclamación exp en el JWT enviado en el encabezado Authorization.

En el flujo de inicio de sesión de Identity Platform, la sesión de IAP sigue siendo válida hasta una hora después de que el usuario haya cerrado sesión.

Petición de inicio de sesión en cuentas de Google

El valor de loginHint definido a través de IapSettings debe coincidir con el dominio del usuario que inicia sesión. Si estos valores no coinciden, se muestra la petición de inicio de sesión si la cookie de IAP se borra o caduca.

Solicitudes de WebSocket

IAP solo admite WebSocket para las solicitudes iniciales y no comprueba la autorización de forma continua. Cuando se recibe una solicitud WebSocket, empieza con una solicitud HTTP Upgrade. IAP evalúa esta solicitud como una solicitud HTTP GET estándar. Una vez que se autoriza la solicitud, la API IAP la transfiere al servidor, lo que abre una conexión persistente. Después de esto, la compra en la aplicación no monitoriza las solicitudes ni actualiza la sesión.

Respuestas de sesiones caducadas

IAP devuelve respuestas diferentes para las sesiones caducadas en función del tipo de solicitud.

Solicitudes no AJAX

En el caso de las solicitudes que no son AJAX, se redirige al usuario al flujo de inicio de sesión para actualizar la sesión. Si el usuario sigue con la sesión iniciada, esta redirección es transparente.

Solicitudes AJAX

Chrome y otros navegadores están eliminando gradualmente las cookies de terceros. Las recomendaciones para hacer solicitudes AJAX de esta página no funcionarán si las cookies de terceros están inhabilitadas. Sin embargo, las recomendaciones proporcionadas seguirán funcionando si tanto la fuente como el destino de las solicitudes AJAX son del mismo sitio.

Para obtener instrucciones sobre cómo gestionar las cookies de terceros en Chrome, consulta el artículo Eliminar, permitir y gestionar cookies en Chrome.

IAP usa cookies para gestionar las sesiones de usuario. También se basa en una secuencia de redirecciones para establecer una sesión como parte de un flujo de inicio de sesión. No siempre es posible establecer una sesión si la aplicación usa el uso compartido de recursos entre dominios (CORS) para enviar solicitudes AJAX a una aplicación protegida por IAP.

Para hacer correctamente una solicitud CORS a una aplicación protegida por IAP, se debe establecer una sesión de IAP fuera de banda. Ten en cuenta que, para que una solicitud AJAX envíe una solicitud CORS desde source_domain->target_domain, donde target_domain aloja la aplicación protegida por IAP, debe establecerse una sesión en target_domain. No se pueden compartir cookies entre source_domain y target_domain.

Una vez que se haya establecido la sesión en target_domain, el desarrollador debe habilitar el envío de credenciales en la solicitud. De forma predeterminada, los métodos de JavaScript no adjuntan cookies a las solicitudes. Para habilitar las credenciales en la solicitud, las solicitudes enviadas con un objeto XMLHttpRequest deben tener la propiedad withCredentials definida como true, mientras que las solicitudes enviadas con un objeto Fetch API deben tener la opción credentials definida como include o same-origin.

En la siguiente guía se recomienda un patrón para que los desarrolladores web puedan establecer y actualizar una sesión de compra en la aplicación correctamente.

Interpretar la respuesta de IAP

En el caso de las solicitudes AJAX, IAP devuelve un código de estado HTTP 401: Unauthorized. Ten en cuenta que la detección de solicitudes AJAX no se puede hacer a la perfección. Si recibes una respuesta con el código de estado 302 en lugar del código de estado 401 a las solicitudes AJAX, puedes añadir un encabezado X-Requested-With con el valor "XMLHttpRequest" a las solicitudes AJAX. Esto indica a las compras en aplicaciones que la solicitud procede de JavaScript.

Gestionar una respuesta 401 AJAX HTTP

Para establecer una sesión de compra en la aplicación después de que la aplicación reciba HTTP 401, la aplicación puede abrir una nueva ventana para la URL target_domain + ?gcp-iap-mode=DO_SESSION_REFRESH. Se trata de un controlador especial que solo establece la sesión de compra en la aplicación en target_domain. Si la ventana permanece abierta, seguirá actualizando la sesión periódicamente y solicitando la intervención del usuario cuando sea necesario. Si quiere, el usuario puede cerrar la ventana y el controlador del estado 401 de HTTP en el código del desarrollador debería volver a abrir una ventana para actualizar la sesión cuando sea necesario.

Paso 1: Modifica el código de tu aplicación

En el siguiente ejemplo se muestra cómo modificar el código de tu aplicación para gestionar el código de estado HTTP 401 y proporcionar un enlace de actualización de la sesión al usuario:

if (response.status === 401) {
  statusElm.innerHTML = 'Login stale. <input type="button" value="Refresh" onclick="sessionRefreshClicked();"/>';
}
Paso 2: Instala un controlador onclick

El código de muestra que aparece a continuación instala un controlador onclick que cierra la ventana después de que se actualice la sesión:

var iapSessionRefreshWindow = null;

function sessionRefreshClicked() {
  if (iapSessionRefreshWindow == null) {
    iapSessionRefreshWindow = window.open("/?gcp-iap-mode=DO_SESSION_REFRESH");
    window.setTimeout(checkSessionRefresh, 500);
  }
  return false;
}

function checkSessionRefresh() {
  if (iapSessionRefreshWindow != null && !iapSessionRefreshWindow.closed) {
    // Attempting to start a new session.
    // XMLHttpRequests is used by the server to identify AJAX requests
    fetch('/favicon.ico', {
          method: "GET",
          credentials: 'include',
          headers: {
              'X-Requested-With': 'XMLHttpRequest'
          }
    .then((response) => {
      // Checking if browser has a session for the requested app
      if (response.status === 401) {
        // No new session detected. Try to get a session again
        window.setTimeout(checkSessionRefresh, 500);
      } else {
        // Session retrieved.
        iapSessionRefreshWindow.close();
        iapSessionRefreshWindow = null;
      }
    })
    });
  } else {
    iapSessionRefreshWindow = null;
  }
}