Autentica usuarios en Firestore con Identity Platform e identidades de Google


En este documento, se muestra cómo configurar el control de acceso basado en usuarios a una base de datos de Firestore mediante Identity Platform como tu identidad de usuario y plataforma de administración de accesos. Identity Platform te permite agregar una capa de autenticación a tu aplicación para que puedas proteger y administrar las credenciales de cliente. Firestore es una base de datos NoSQL flexible orientada a documentos. Usa un lenguaje de reglas denominado reglas de seguridad de Firestore para controlar el acceso a estos datos, por lo que no necesitas escribir código de autorización del lado del servidor.

Este documento está dirigido a desarrolladores y profesionales de seguridad que deseen usar Firestore con las reglas de seguridad de Firestore y que deseen autenticar a sus usuarios con Identity Platform con un proveedor de acceso externo como Google. En el código de este documento, se muestran dos formas de usar Identity Platform y Firestore:

  • Llamadas a la API de REST mediante JavaScript para llamar a las API de Identity Platform y Firestore. Este enfoque te permite tener control total sobre la forma en que tu app web crea solicitudes para Identity Platform.
  • SDK de cliente de Identity Platform, mediante el SDK de cliente de Identity Platform y el SDK de Firestore para administrar el proceso de acceso a Identity Platform y consultar Firestore. El SDK proporciona funciones de wrapper de JavaScript a través de las API de REST de Identity Platform, que te permiten llamar a Identity Platform mediante funciones y objetos de JavaScript, en lugar de crear solicitudes HTTP de forma manual.

El SDK de cliente de Identity Platform y el SDK de cliente de Firebase comparten el mismo SDK. El SDK admite todas las capacidades de Identity Platform. Para preservar la retrocompatibilidad, el SDK retiene la marca de Firebase.

Arquitectura

En el siguiente diagrama, se muestra la arquitectura lógica que se describe en este documento:

Diagrama de arquitectura lógica

Además de Identity Platform y Firestore, en el documento, se usa y se demuestran los siguientes componentes:

  • Aplicación web: Una app que permite que los usuarios accedan a Identity Platform con identidades de Google Luego, consulta Firestore para obtener información sobre el usuario que accedió.
  • Acceso con Google: El proveedor de identidad que se usa en este instructivo.
  • Controlador de autenticación: Un extremo de servicio que obtiene la respuesta de Google, realiza el acceso con Identity Platform y envía el resultado a la app web para completar el acceso.

Objetivos

  • Configurar Identity Platform para tu proyecto de Google Cloud.
  • Agregar Google como proveedor de acceso para Identity Platform.
  • Usar las reglas de seguridad de Firestore para controlar el acceso a una base de datos de Firestore.
  • Hacer que los usuarios accedan a una aplicación web con las API de Identity Platform y el SDK de cliente de Identity Platform.
  • Acceder de forma segura a Firestore desde una app web del lado del cliente mediante la API de REST de Firestore y el SDK del cliente de JavaScript para Firestore.

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud califiquen para obtener una prueba gratuita.

Antes de comenzar

  1. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

    Si seleccionas un proyecto existente, debes seleccionar un proyecto que cumpla con las siguientes condiciones:

    • Datastore no está habilitado.
    • App Engine no está habilitado.
    • El proyecto no incluye una base de datos de Firestore con reglas de seguridad existentes. Reemplaza las reglas existentes con las reglas que se describen en este documento.
  2. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  3. Habilita Identity Platform:
    1. Ve a la página Marketplace de Identity Platform en la consola de Cloud.

      Ir a la página Marketplace de Identity Platform

    2. Haz clic en Habilitar Identity Platform y espera a que se complete la operación.
  4. Habilita Firestore:
    1. En la consola de Google Cloud, abre el menú del lado izquierdo y selecciona Firestore.
    2. Selecciona un modo de Firestore. Haz clic en Seleccionar modo nativo.
    3. Elige dónde almacenar tus datos. Selecciona la región más cercana a tu ubicación. Haga clic en Crear base de datos.

Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.

Configura Identity Platform

Para habilitar la autenticación de usuario en Identity Platform, debes agregar proveedores de identidad.

Antes de configurar un proveedor de Google en Identity Platform, debes configurar la pantalla de consentimiento de OAuth de Google. Los usuarios ven esta pantalla de consentimiento la primera vez que acceden a tu app web. En la configuración de la pantalla de consentimiento de OAuth, puedes configurar atributos como el nombre de tu aplicación, el logotipo de tu aplicación y una dirección de correo electrónico de asistencia.

  1. En la consola de Google Cloud, ve a la página Proveedores de identidad.

    Ir a la página Proveedores de identidad

  2. Haz clic en Agregar un proveedor.
  3. Selecciona Google y, en la página Proveedor de identidad nuevo, haz clic en el vínculo API y servicios. Se abrirá la página Credenciales en una pestaña nueva. No cierres la pestaña anterior porque debes copiar de la página Credenciales a la página Proveedor de identidad nuevo.
  4. En la página Credenciales, haz clic en las credenciales Cliente web (creado automáticamente por el servicio de Google).
  5. Copia el valor del ID de cliente, ve a la pestaña que muestra la página Proveedor de identidad nuevo y pega el valor en el campo ID de cliente web. Repite este paso para copiar el valor Secreto de cliente en el campo Secreto de cliente web.
  6. En la página Proveedor de identidad nuevo, haz clic en Guardar.
  7. Regresa a la página Credenciales y haz clic en Pantalla de consentimiento de OAuth.
  8. Selecciona Externa y, luego, haz clic en Crear.
  9. En la página Pantalla de consentimiento de OAuth, agrega la siguiente información:
    • Nombre de la aplicación: Identity Platform Tutorial
    • Correo electrónico de asistencia: Selecciona tu dirección de correo electrónico en la lista desplegable.
  10. Haz clic en Guardar.
  11. En la página Editar registro de aplicaciones, agrega la siguiente información:
    • Nombre de la app: Identity Platform Tutorial
    • Correo electrónico de asistencia del usuario: selecciona tu dirección de correo electrónico en la lista desplegable.
    • Direcciones de correo electrónico: Escribe tu dirección de correo electrónico.
  12. Haga clic en Guardar y continuar.
  13. En las páginas Alcances e Información opcional, haz clic en Guardar y continuar.
  14. En la página Resumen, haz clic en Volver al panel.

Configura Firestore

La base de datos de Firestore nueva que creaste está vacía actualmente. La nueva base de datos de Firestore también tiene un conjunto predeterminado de reglas de seguridad que permiten a cualquier persona realizar operaciones de lectura en la base de datos. Estas reglas predeterminadas evitan que alguien escriba en la base de datos. En los pasos siguientes, propagarás la base de datos con datos y actualizarás las reglas de seguridad para limitar las solicitudes de lectura (consulta) a los usuarios autorizados.

Crea datos de prueba en Firestore

En este procedimiento, debes probar las reglas de seguridad mediante una consulta a las colecciones de Firestore desde una aplicación web.

Primero, crea varios documentos para ayudarte a probar las reglas de seguridad de Firestore. Los nombres de las colecciones y los campos distinguen mayúsculas de minúsculas. Usa nombres en minúscula para la recopilación y los campos a fin de evitar que la aplicación web falle cuando envía una consulta a Firestore.

  1. Ve a la página Firewalls en la consola de Google Cloud.
  2. Haz clic en Iniciar colección.
  3. En el campo ID de colección, escribe customers.
  4. Crea un documento con la siguiente información:

    ID de documento: bob@example.com

    Nombre del campo Tipo de campo Valor del campo
    name String Bob
    empresa String
    
    ExampleOrganization
  5. Haz clic en Guardar y agregar otro.

  6. Haz clic en Borrar valores de campo.

  7. Ingresa la siguiente información:

  8. ID del documento: Tu dirección de correo electrónico

    Nombre del campo Tipo de campo Valor del campo
    name String Su nombre
    empresa String El nombre de tu empresa
  9. Haz clic en Guardar.

Crea reglas de seguridad de Firestore

Las reglas de seguridad de Firestore se pueden evaluar con metadatos de autenticación de usuarios, datos de consultas entrantes y datos existentes en tu base de datos.

En este procedimiento, se crea una regla de seguridad para Firestore que se basa en la dirección de correo electrónico del usuario que accedió y el nombre del proveedor.

Usa Firebase console para administrar las reglas de seguridad de Firestore.

  1. Abre Firebase console y selecciona tu proyecto.
  2. Haz clic en Firestore en el lado izquierdo de la pantalla.
  3. En la página Firestore, haz clic en la pestaña Reglas.
  4. Si eliges usar un proyecto existente que tiene una base de datos de Firestore con reglas de seguridad y planeas limpiar el proyecto cuando termines este documento, anota tus reglas de seguridad existentes.
  5. Reemplaza las reglas existentes por la siguiente:

    rules_version = '2';
    service cloud.firestore {
     match /databases/{database}/documents {
      match /customers/{customerID} {
      allow read:
       if request.auth.uid != null
         && request.auth.token.firebase.sign_in_provider == "google.com"
         && request.auth.token.email == customerID
        }
      }
    }
    

    Esta regla otorga permiso de solo lectura para la colección customers. La regla verifica que hayas accedido a través del proveedor de acceso de Google que configuraste en Identity Platform. También se asegura de que solo puedas recuperar los documentos que tengan un ID de cliente que coincida con tu dirección de correo electrónico.

  6. Haz clic en Publish (Publicar).

Configura el entorno de pruebas

Para probar tus reglas de seguridad de Firestore, primero debes crear una aplicación web que requiera que los usuarios accedan. La aplicación web está disponible en GitHub y se descarga en un entorno de Cloud Shell, donde puedes probar la aplicación. Después de que el usuario accede, la aplicación web lee los documentos de Firestore y muestra su contenido.

Configura la aplicación web

  1. Ir a la página Proveedores de Identity Platform.

    Ir a la página Proveedores de Identity Platform

  2. En el lado derecho de la página, haz clic en Detalles de configuración de la aplicación.
  3. Copia los valores enumerados junto a apiKey y authDomain en el portapapeles y, luego, haz clic en Cerrar.
  4. Haz clic en Google Cloud en la parte superior de la página y copia el ID del proyecto de la tarjeta Información del proyecto.
  5. Haz clic en Abrir en Cloud Shell para abrir Cloud Shell, clonar el repositorio de GitHub, y abrir el archivo config.js. Cuando aparezca el diálogo Abrir en Cloud Shell, haz clic en Confirmar.

    Abrir en Cloud Shell

  6. En el archivo config.js, reemplaza los marcadores de posición [API_KEY], [AUTH_DOMAIN] y [PROJECT_ID] con los valores que copiaste en el paso anterior. Tu código inyecta estos valores en la URL y el cuerpo de los mensajes que crea cuando envía solicitudes a Identity Platform.

Registra el controlador de autenticación personalizado

Cuando los usuarios acceden a tu app web, se los redirecciona para que accedan con Google como un proveedor de identidad. Después de que el usuario accede correctamente a Google, este muestra una respuesta de redireccionamiento (302) con el token del usuario al controlador de autenticación, como se muestra en el diagrama de arquitectura. En OAuth 2.0, debes registrar todas las URL de redireccionamiento en la configuración del proveedor con anticipación para evitar que el proveedor envíe tu token a un destino desconocido. La página de registro de la URL de redireccionamiento en el sitio web de OAuth 2.0 explica los motivos de esta restricción.

En este paso, actualizarás la lista de las URL de redireccionamiento autorizadas para confiar en los controladores de autenticación que se usan en este documento.

La lista de URL forma parte de la configuración de cliente de Google OAuth 2.0, es decir, la página en la que copiaste el ID de cliente y el secreto del cliente desde el configurado Identity Platform.

En esta arquitectura, usarás dos controladores de autenticación diferentes:

  • Un controlador de autenticación que aloja Identity Platform.
  • Un controlador de autenticación personalizado que aloja la app web.

Se puede acceder al controlador de autenticación alojado en Identity Platform a través del siguiente extremo, que es administrado por Google: https://[YOUR_PROJECT_ID].firebaseapp.com/__/auth/handler

Para usar este controlador, no necesitas actualizar la lista de URL autorizadas en la configuración del cliente de Google OAuth 2.0. Cuando habilitaste Identity Platform antes en este documento, se agregó la URL de forma automática a la lista de URL autorizadas.

Si usas el SDK de cliente de Identity Platform, este usa este controlador de autenticación integrado. El controlador de autenticación para Identity Platform requiere que tu aplicación web use este SDK, ya que el SDK intercambia objetos de estado con el controlador. Por ejemplo, el SDK informa al controlador dónde redireccionar a los usuarios después de acceder correctamente a Identity Platform.

En el controlador de autenticación personalizado alojado por la aplicación web, cuando usas las API de REST de Identity Platform directamente desde JavaScript, te recomendamos implementar y alojar tu propio controlador de autenticación en lugar del SDK.

Este documento contiene un controlador de autenticación de muestra que administra el proceso de acceso a Identity Platform cuando recibe el token de usuario de Google. Debes agregar la URL del controlador personalizado a la lista de URL autorizadas en tu configuración de cliente de Google OAuth 2.0.

En este documento, ejecutarás la app web desde Cloud Shell. Después de iniciar la app web, busca el nombre de host de tu instancia de Cloud Shell y actualiza la configuración del proveedor según corresponda.

  1. Ejecuta la aplicación web desde Cloud Shell:

    npm install
    node app.js
    
  2. Espera a que aparezca el siguiente resultado: Example app listening on port 8080!

  3. Haz clic en el ícono Vista previa en la Web y, luego, en Vista previa en el puerto 8080. Espera a que la nueva pestaña muestre la página web y copia el valor en URL del controlador de autenticación (para cliente de Google OAuth 2.0).

  4. Ve a la página Credenciales.
    Ir a la página Credenciales

  5. En la página Credenciales, haz clic en Cliente web (creado automáticamente por el servicio de Google).

  6. En la página URI de redireccionamiento autorizados, haz clic en Agregar URI y pega la URL que copiaste antes.

  7. Haz clic en Guardar y deja la app web ejecutándose.

Autoriza el dominio de la aplicación web

Cuando usas el controlador de autenticación de Identity Platform, el controlador te redirecciona a la aplicación web, junto con tu información de usuario y tokens. Para evitar enviar información a un dominio no autorizado, debes autorizar el dominio en el que se ejecuta tu aplicación web.

  1. Regresa a la página web predeterminada de la aplicación web y copia el valor que aparece en Nombre de host (para dominios autorizados de Identity Platform).
  2. Ir a la página Configuración de Identity Platform.

    Ir a la página Configuración de Identity Platform

  3. Haz clic en la pestaña Seguridad y, luego, en Agregar dominio.
  4. Pega el dominio que copió, haz clic en Agregar y, luego, en Guardar.
  5. Mantén la app web en ejecución en Cloud Shell. La necesitarás para la siguiente tarea.

Accede a Identity Platform con tu identidad de Google

En el siguiente diagrama, se expande el diagrama de arquitectura de alto nivel al comienzo de esta guía. Este diagrama analiza los detalles del proceso de autenticación que se describen en este documento para mostrar el flujo cronológico de los eventos. Los eventos comienzan con el usuario cuando hace clic en un botón de acceso y finalizan con la aplicación web que recupera datos de Firestore, mediante la identidad del usuario:

Arquitectura de alto nivel

  1. Un usuario de tu aplicación web hace clic en Acceder con Google en la aplicación web.
  2. La aplicación web consulta Identity Platform para obtener la URL de acceso del proveedor de identidad elegido (en este caso, Google).
  3. La aplicación web redirecciona al usuario a la página de acceso de tu proveedor de identidad, junto con una URL de devolución de llamada que apunta al controlador de autenticación.
  4. En la página de acceso del proveedor, el usuario ingresa sus credenciales y consentimientos en la autorización que solicita la app web.
  5. Una vez que el usuario accede correctamente, el proveedor genera un token y envía un redireccionamiento a la URL de devolución de llamada proporcionada antes.
  6. El controlador de autenticación recibe el token emitido por Google y lo envía a Identity Platform para que el usuario acceda. Identity Platform valida el token, accede al usuario y muestra un token de ID y un token de actualización emitido por Identity Platform con la información del usuario. Cuando Identity Platform accede a un usuario por primera vez, crea un perfil de usuario coincidente en su base de datos. La información de la cuenta que Google proporciona se usa para propagar el perfil del usuario.
  7. Después de acceder a Identity Platform, el controlador te redirecciona de vuelta a la aplicación web, junto con los tokens nuevos que obtuvo de Identity Platform.
  8. Para enviar solicitudes a Firestore, la aplicación web adjunta el token de ID del usuario a cada solicitud de Firestore. Las reglas de seguridad de Firestore determinan que Firestore trata cualquier solicitud sin un token de ID como una solicitud anónima y se rechaza.
  9. Los tokens de ID emitidos por Identity Platform vencen después de una hora. Si el token de ID vence, la app web usa el token de actualización almacenado en caché para recuperar un token de ID nuevo desde Identity Platform.

La app web de muestra demuestra cómo interactuar con Identity Platform y Firestore de dos maneras.

El primer método es con la API de REST de Identity Platform:

  • Esta técnica usa un código personalizado que llama a las API de REST de Identity Platform mediante JavaScript.
  • Las llamadas a la API se implementan en el archivo site/identity-platform-auth-helper.js. El controlador de autenticación se implementa en el archivo views/auth-handler.ejs.
  • El asistente y el controlador intercambian objetos de estado para habilitar el redireccionamiento a la app web después de acceder de forma correcta.

El segundo método es con el SDK del cliente de Identity Platform:

  • Con esta técnica, el SDK controla el proceso de inicio de sesión.
  • El SDK implementa todas las llamadas a la API requeridas y expone un conjunto de funciones al desarrollador para controlar qué flujo de acceso se debe iniciar.

Accede con las API de REST de Identity Platform

Existen dos llamadas a la API principales que controlan el flujo de acceso con Google como el proveedor de identidad.

Las dos llamadas principales de la API que controlan el flujo de acceso con Google como proveedor.

  • Obtiene el identificador y la URL del proveedor. El método accounts.createAuthUri muestra una URL de autorización para el proveedor de identidad dado. La app web navega a la URL de autorización que se muestra para comenzar el proceso de inicio de sesión con el proveedor de identidad seleccionado (por ejemplo, Google).

    En el siguiente fragmento de código, se muestra cómo realizar una llamada a esta API:

    IdentityPlatformAuthHelper.prototype.createAuthUri = function(providerId, tenantId) {
      // https://cloud.google.com/identity-platform/docs/reference/rest/v1/accounts/createAuthUri
      const createAuthUriUrl = `${this.identityPlatformBaseUrl}/accounts:createAuthUri?key=${config.apiKey}`;
      const request = {
        'providerId' : providerId,
        'tenantId' : tenantId,
        'continueUri' : this.authHandlerUrl,
      };
    
      return fetch(
          createAuthUriUrl,
          {
            contentType: 'application/json',
            method: 'POST',
            body: JSON.stringify(request)
          }
        )
      .then(response => response.json())
      .then(data => {
        return {
          "authUri" : data.authUri,
          "sessionId" : data.sessionId
        };
      })
      .catch(error => {
        console.error(error);
      });
    };
  • Accede a Identity Platform con un token emitido por Google. El método accounts.signInWithIdp inicia la sesión del usuario en Identity Platform mediante la respuesta de autorización del proveedor de identidad. La API responde a esta solicitud con un token nuevo, que emite Identity Platform. La app web llama a esta API después de recibir una respuesta de autorización correcta del proveedor de identidad. En el siguiente fragmento de código, se muestra cómo realizar una llamada a esta API:

    IdentityPlatformAuthHelper.prototype.signInWithIdp = function(data) {
      authState = this.getAuthState();
      this.authHandlerUrl = authState.authHandlerUrl;
    
      // https://cloud.google.com/identity-platform/docs/reference/rest/v1/accounts/signInWithIdp
      const signInWithIdpUrl = `${this.identityPlatformBaseUrl}/accounts:signInWithIdp?key=${config.apiKey}`;
    
      const request = {
          'requestUri' : this.authHandlerUrl,
          'sessionId' : authState.sessionId,
          'returnRefreshToken' : true,
          'returnSecureToken' : true,
          'tenantId' : authState.tenantId
        };
    
      if (authState.providerId == 'google.com' || authState.providerId.startsWith('saml.')) {
        request.postBody = `${data}&providerId=${authState.providerId}`;
      } else {
        throw new Error('This sample script only supports the google.com and SAML providers for Identity Platform');
      }
    
      fetch(
          signInWithIdpUrl,
          {
            contentType: 'application/json',
            method: 'POST',
            body: JSON.stringify(request)
          }
        )
      .then(response => response.json())
      .then(data => {
        this.user = data;
        this.signedInHandler(this.user);
      })
      .catch(error => {
        console.error(error);
      });
    }

    El valor del campo postBody tiene diferentes formatos, según el proveedor de identidad seleccionado y el protocolo de autorización que usa. El código maneja el proveedor de identidad de Google con su token OpenID Connect (OIDC) y los proveedores de identidad basados en SAML con sus respuestas SAML proporcionadas. Si usas otros tipos de tokens de autorización, como los tokens de acceso de OAuth 2.0 o de OAuth 1.0, consulta la documentación de la API de tu proveedor.

Cuando un usuario accede a tu app web, esta puede enviar consultas a Firestore.

Flujo de eventos cuando la aplicación web envía una consulta a Firestore

Antes de que el código pueda activar una solicitud a las API de REST de Firestore, agrega el token de ID que Identity Platform emitió y firmó en la solicitud. En el siguiente fragmento de código, se muestra cómo crear la solicitud:

function showCustomerInformation(userEmail) {
  $('#customer-information').show();
  $('#output').empty();

  const idTokenPromise = authHelper.getIdToken();
  const firestoreEndpoint = 'https://firestore.googleapis.com/v1';
  const defaultDbPath = `projects/${config.projectId}/databases/(default)/documents`;
  const collectionId = 'customers';

  // Call Firestore via its REST API and authenticate with the user's ID token
  idTokenPromise
  .then(idToken => {
    console.log(`JWT Token: ${idToken}`);
    return fetch(
      `${firestoreEndpoint}/${defaultDbPath}/${collectionId}/${userEmail}`,
      {
        headers: {
          'Authorization': 'Bearer ' + idToken
        },
        contentType: 'application/json',
        method: 'GET'
      })
  })
  .then(response => response.json())
  .then(data => {
      if (data.error) {
        throw data.error.message;
      }
      var fields = data.fields;
      $('#output').append($('<p>').text(`Id: ${userEmail}`));
      $('#output').append($('<p>').text(`Name: ${fields.name.stringValue}`));
      $('#output').append($('<p>').text(`Company: ${fields.company.stringValue}`));
      $('#output').append($('<p>').text(`Doc path: ${data.name}`));
      $('#output').append($('<p>').text(`Doc URL: ${firestoreEndpoint}/${data.name}`));
  })
  .catch(error => {
    console.error(error);
    $('#output').text("Error: " + JSON.stringify(error));
  });
}

La función IdentityPlatformAuthHelper.getIdToken() muestra un token de ID válido con la forma de un token web JSON (JWT) mediante la recuperación de un token de almacenamiento en caché del navegador. Si el token ya venció, la función lo renueva mediante una llamada a la API de Identity Platform a fin de intercambiar un token de actualización para un token de ID nuevo.

En el siguiente fragmento, se muestra cómo verificar si el token de ID existente aún es válido o está vencido, y cómo actualizarlo según corresponda llamando a Identity Platform:

IdentityPlatformAuthHelper.prototype.getIdToken = function() {
  const token = this.jwtDecode(this.user.idToken);

  // If exp has passed, refresh the token
  if (Date.now() > token.payload.exp * 1000) {
    return this.refreshToken(this.user.refreshToken);
  }
  return Promise.resolve(this.user.idToken);
}

IdentityPlatformAuthHelper.prototype.jwtDecode = function(t) {
  const token = {};
  token.raw = t;
  token.header = JSON.parse(window.atob(t.split('.')[0]));
  token.payload = JSON.parse(window.atob(t.split('.')[1]));
  return token;
}

IdentityPlatformAuthHelper.prototype.refreshToken = function(refreshToken) {
  // https://cloud.google.com/identity-platform/docs/reference/rest/client#section-refresh-token
  const tokenUrl = `https://securetoken.googleapis.com/v1/token?key=${config.apiKey}`;
  const requestBody = new URLSearchParams(`grant_type=refresh_token&refresh_token=${refreshToken}`);

  return fetch(
      tokenUrl,
      {
        contentType: 'application/x-www-form-urlencoded',
        method: 'POST',
        body: requestBody
      }
    )
  .then(response => response.json())
  .then(data => {
    this.user.idToken = data.id_token;
    this.user.refreshToken = data.refresh_token;
    return this.user.idToken;
  })
  .catch(error => {
    console.error(error);
  });
}

Realiza los siguientes pasos para acceder a Identity Platform con tu identidad de Google:

  1. Regresa a la pestaña que muestra la página predeterminada de la app web. Si ya cerraste esa pestaña, regresa a la página de Cloud Shell, haz clic en Vista previa en la Web y, luego, en Vista previa en el puerto 8080. Espera a que la nueva pestaña muestre la página web.
  2. Cambia la dirección en el navegador para que se muestre la página customer-info-with-api.html. La URL nueva tiene el siguiente formato: https://random_prefix-devshell.appspot.com/customer-info-with-api.html
  3. Haz clic en Acceder con Google y acceda con sus credenciales. Después de acceder, aparecerá un cuadro de texto con tu dirección de correo electrónico.

    Si deseas decodificar el JWT para ver la información del usuario que proporciona Identity Platform y Google, haz lo siguiente. También puedes continuar con el siguiente paso.

    La información del usuario se encuentra en la (segunda) parte de la carga útil del JWT y se codifica en base64. Para decodificar la segunda parte del JWT y, luego, imprimir la información en un archivo JSON mediante jq, ejecuta el siguiente comando en Cloud Shell:

    token=[PASTE_JWT_STRING_HERE]
    echo $token | awk '{split($0, a, "."); print a[2]; }' | base64 -d | jq
    

    Continúa con la consulta de Firestore para otros documentos.

  4. Haz clic en Obtener información del cliente. Tu nombre y el nombre de la empresa aparecerán a medida que los ingresaste en la base de datos de Firestore.

  5. Cambia la dirección de correo electrónico a bob@example.com y, luego, haz clic en Acceder con Google. La respuesta esta vez es el siguiente mensaje de error:

    Error: "Missing or insufficient permissions." The security rule you added to Firestore limits your access to documents with an ID that matches your email address, as it appears in the token that Identity Platform created.

  6. No cierres la página web. La usarás en el siguiente procedimiento.

Accede con el SDK de cliente de Identity Platform

En lugar de elaborar manualmente las solicitudes a Identity Platform, puedes usar el SDK de cliente de Identity Platform. El SDK administra el proceso de acceso y proporciona funciones para controlar el flujo de acceso, como qué proveedor usar o si se debe usar un redireccionamiento o una ventana emergente.

Para usar el SDK de cliente de Identity Platform, debes incluir varios archivos de secuencia de comandos en tu página HTML. En el siguiente fragmento, se muestran las secuencias de comandos que necesitas:

<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-firestore.js"></script>

En el siguiente fragmento, se muestra cómo usar el SDK para acceder con el proveedor de Google.

$('#sign-in').click((event) => {
  provider = new firebase.auth.GoogleAuthProvider();
  //firebase.auth().signInWithPopup(provider)
  firebase.auth().signInWithRedirect(provider)
  .then((result) => {
    console.log(result);
  })
  .catch((error) => {
    console.error(error);
  });
});

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    $('#logged-out').hide();
    /* If the provider gives a display name, use the name for the
    personal welcome message. Otherwise, use the user's email. */
    const welcomeName = user.displayName ? user.displayName : user.email;
    console.log(firebase.auth().currentUser);
    $('#user').text(welcomeName);
    $('#logged-in').show();
    $('#email').val(firebase.auth().currentUser.email);
  } else {
    $('#logged-in').hide();
    $('#logged-out').show();
    $('#email').val('');
  }
  $('#customer-information').hide();
});

$('#sign-out').click(function(event) {
  firebase.auth().signOut().then(function() {
    console.log('Sign out successful');
  }, function(error) {
    console.error(error);
  });
});

La función firebase.auth().signInWithRedirect() inicia el proceso de acceso en la misma ventana del navegador y redirecciona al usuario a la página de acceso del proveedor. El uso de GoogleAuthProvider le indica a la función que inicie el flujo de acceso de Google.

Para reemplazar el comportamiento de redireccionamiento con un comportamiento de ventana emergente, en su lugar, llama a la función signInWithPopup.

Para usar otros proveedores de autenticación, agrega cualquier tipo que implemente la interfaz firebase.auth.AuthProvider. Para asegurarse de incluir todos los parámetros obligatorios, sigue la documentación del proveedor seleccionado.

La función firebase.auth().onAuthStateChanged es un observador que se activa cuando accedes y cuando cierras sesión. Cuando accedes, el código de la app web completa la página web con la información tomada del objeto Usuario y oculta el botón de acceso. Cuando el usuario cierra sesión, el código borra la página web y muestra el botón de acceso otra vez.

El SDK de cliente de Identity Platform se integra con el SDK de Firestore. En cada consulta, el SDK de Firestore adjunta un token de ID válido, ya que lo recupera del SDK de cliente de Identity Platform. El SDK de cliente de Identity Platform es responsable de actualizar el token de ID cuando vence.

En el siguiente fragmento de código, se muestra cómo consultar Firestore con el SDK de Firestore:

function showCustomerInformation(userEmail) {
  $('#customer-information').show();
  $('#output').empty();

  const db = firebase.firestore();
  const collectionId = 'customers';

  query = db.collection(collectionId).doc(userEmail).get();
  query.then((doc) => {
    var fields = doc.data();
    $('#output').append($('<p>').text(`Id: ${doc.id}`));
    $('#output').append($('<p>').text(`Name: ${fields.name}`));
    $('#output').append($('<p>').text(`Company: ${fields.company}`));
  }).catch((error) => {
    console.error(error);
    $('#output').text("Error: " + error.toString());
  });
}

No es necesario que escribas el código para agregar el token de ID a la consulta. El SDK de Firestore y el SDK del cliente de Identity Platform administran el proceso de autenticación.

Realiza los siguientes pasos para acceder a Identity Platform con tu identidad de Google y, luego, consulta Firestore:

  1. Si ya cerraste la pestaña correspondiente de la aplicación web, regresa a la Cloud Shell página, hacer clic en Vista previa en la Web y, luego, en Vista previa en el puerto 8080. Espera a que la nueva pestaña muestre la página web.
  2. Cambia la dirección en el navegador para mostrar la página customer-info-with-sdk.html. La URL nueva tiene el siguiente formato: https://random_prefix-devshell.appspot.com/customer-info-with-sdk.html
  3. Haz clic en Acceder con Google y acceda con sus credenciales. Después de acceder, aparecerá un cuadro de texto con tu dirección de correo electrónico.
  4. Haz clic en Obtener información del cliente. Aparecerán tu nombre y el de tu empresa, tal como los ingresaste en la base de datos de Firestore.
  5. Cambia la dirección de correo electrónico a bob@example.com y, luego, haz clic en Acceder con Google. La respuesta esta vez es un mensaje de error:

    Error: FirebaseError: [code=permission-denied]: Missing or insufficient Permissions.

    Si desea obtener más información sobre el uso de JavaScript para consultar Firestore, consulta la documentación de Firestore.

Soluciona problemas en la aplicación web

Obtén información sobre los pasos para solucionar problemas que pueden servirte si tienes alguno de los siguientes problemas cuando ejecutas la app web.

Errores por navegar en la aplicación web

Error Notas
Verás alguno de los siguientes mensajes de error:

Error:Could not connect to Cloud Shell on port 8080

Error:No active Cloud Shell
Asegúrate de que Cloud Shell esté abierto y que la app web esté en ejecución, como se explica en Registra el controlador de autenticación personalizado. Si abres una sesión nueva de Cloud Shell, cambia el directorio de trabajo al directorio de la app web antes de ejecutarla

cd "$HOME"/cloudshell_open/securing-cloud-firestore-with-identity-platform

Después de ejecutar la app web, verifica que se muestre el siguiente resultado:

Example app listening on port 8080!

Errores cuando accedes a Google

Error Notas
No sucede nada cuando haces clic en Acceder con Google. . Verás el siguiente código de error:

Cannot GET /undefined
Asegúrate de haber configurado las variables apiKey y authDomain en el archivo config.js, como se explica en Configura la aplicación web.
En la página de acceso de Google, verás el siguiente mensaje de error:

Authorization Error - Error 400: redirect_uri_mismatch
La URL de redireccionamiento enviada a Google no coincide con la lista de URL autorizadas para el cliente de OAuth. Asegúrate de haber configurado los URI de redireccionamiento autorizados, como se explica en Registra el controlador de autenticación personalizado.
Cuando accedas a Google con el SDK de Identity Platform, verás el siguiente mensaje de error:

This domain (***) is not authorized to run this operation. Add it to the OAuth redirect domains list in the Firebase console -> Auth section -> Sign-in method tab
Este error puede aparecer si el dominio que usa Cloud Shell no existe en la lista de dominios permitidos de Identity Platform. Para verificar que el nombre de dominio se agregó a la lista de dominios, sigue los pasos en Autoriza el dominio de la app web.

Errores cuando recuperas información del cliente

Error Notas
Verás alguno de los siguientes mensajes de error:

Error: FirebaseError: [code=permission-denied]: Missing or insufficient permissions

Error: Missing or insufficient permissions
Es posible que las reglas de seguridad de Firestore no hayan validado el token enviado a Firestore. Asegúrate de que las reglas de seguridad de Firestore estén configuradas correctamente, como se explica en Crea reglas de seguridad de Firestore.
Verás alguno de los siguientes mensajes de error:

Error: FirebaseError: [code=unavailable]: Failed to get document because the client is offline

Error: "The project *** does not exist or it does not contain an active Datastore or Firestore database

Error: "Project id [PROJECT_ID] is malformed: it either contains invalid characters or is too long
Asegúrate de configurar la propiedad projectId en el archivo config.js, como se explica en Configura la aplicación web.

Limpia

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

  1. En la consola de Google Cloud, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

Borra los recursos individuales

  1. En Cloud Shell, presiona Ctrl+C para detener la aplicación web.
  2. Borra el directorio del repositorio clonado:

    rm -rf "$HOME"/cloudshell_open/securing-cloud-firestore-with-identity-platform
    
  3. Ir a la página Configuración de Identity Platform.

    Ir a la página Configuración de Identity Platform

  4. Haz clic en la pestaña Seguridad, borra el dominio que agregaste antes y, luego, haz clic en Guardar.

  5. Ve a la página Proveedores de identidad.

    Ir a la página Proveedores de identidad

  6. Borra el proveedor de Google que agregaste antes.

  7. Ve a API y servicios y, luego, a la página Credenciales.

    Ir a la página Credenciales

  8. En la página Credenciales, haz clic en el Cliente web (creado automáticamente por el servicio de Google).

  9. En la página URI de redireccionamiento autorizados, borra la URL que pegaste antes y, luego, haz clic en Guardar.

  10. Abre Firebase console y, en el panel de navegación de la consola, haz clic en tu proyecto.

  11. Selecciona la opción Base de datos en el menú Desarrollar del lado izquierdo.

  12. En la página Base de datos, haz clic en la pestaña Reglas.

  13. Reemplaza las reglas de seguridad actuales con las que tenías antes de comenzar el documento y, luego, haz clic en Publicar.

  14. Ve a la página Firewalls en la consola de Google Cloud.

  15. Haz clic en el menú a la izquierda de la colección Clientes y, luego, haz clic en Borrar colección.

  16. En la ventana emergente de confirmación para borrar, escribe customers en el campo ID de colección y haz clic en Borrar.

¿Qué sigue?

Explora arquitecturas de referencia, diagramas y prácticas recomendadas sobre Google Cloud. Consulta nuestro Cloud Architecture Center.