Authentifier des utilisateurs auprès de Firestore avec Identity Platform et les identités Google


Ce document explique comment configurer le contrôle des accès basé sur l'utilisateur à une base de données Firestore à l'aide d'Identity Platform en tant que plate-forme de gestion de l'authentification et des accès utilisateur. Identity Platform vous permet d'ajouter une couche d'authentification à votre application afin de protéger et de gérer les identifiants client. Firestore est une base de données NoSQL flexible orientée documents. Elle utilise un langage de règles appelé Règles de sécurité Firestore pour contrôler l'accès à ces données. Vous n'avez donc pas besoin d'écrire de code d'autorisation côté serveur.

Ce document est destiné aux développeurs et aux professionnels de la sécurité qui souhaitent utiliser Firestore avec les règles de sécurité Firestore et qui souhaitent authentifier leurs utilisateurs avec Identity Platform à l'aide d'un fournisseur de connexion externe tel que Google. Le code de ce document illustre deux manières d'utiliser Identity Platform et Firestore :

  • Via les appels d'API REST, en utilisant JavaScript pour appeler les API Identity Platform et Firestore. Cette approche vous permet de contrôler entièrement la manière dont votre application Web crée des requêtes pour Identity Platform.
  • Via le SDK client Identity Platform, en utilisant le SDK client Identity Platform et le SDK Firestore pour gérer le processus de connexion à Identity Platform en interrogeant Firestore. Le SDK fournit des fonctions de wrapper JavaScript sur les API REST d'Identity Platform, ce qui vous permet d'appeler Identity Platform à l'aide de fonctions et d'objets JavaScript, au lieu de créer manuellement des requêtes HTTP.

Le SDK client Identity Platform et le SDK client Firebase partagent le même SDK. Le SDK est compatible avec toutes les fonctionnalités d'Identity Platform. Pour préserver la rétrocompatibilité, le SDK conserve la marque Firebase.

Architecture

Le schéma suivant illustre l'architecture logique qui est décrite dans ce document :

Schéma de l'architecture logique.

En plus d'Identity Platform et de Firestore, ce document utilise et présente les composants suivants :

  • Application Web : application qui permet aux utilisateurs de se connecter à Identity Platform avec des identités Google. Elle interroge ensuite Firestore pour obtenir des informations sur l'utilisateur connecté.
  • Google Sign-In : fournisseur d'identité utilisé dans cet exemple.
  • Gestionnaire d'authentification : point de terminaison du service qui obtient la réponse de Google, effectue la connexion avec Identity Platform et renvoie le résultat à l'application Web pour terminer le processus de connexion.

Objectifs

  • Configurer Identity Platform pour votre projet Google Cloud.
  • Ajouter Google en tant que fournisseur de connexion pour Identity Platform.
  • Utiliser les règles de sécurité Firestore pour contrôler l'accès à une base de données Firestore.
  • Se connecter à une application Web à l'aide des API Identity Platform et du SDK client Identity Platform.
  • Accéder de manière sécurisée à Firestore à partir d'une application Web côté client à l'aide de l'API REST de Firestore et du SDK client JavaScript Firestore.

Coûts

Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Avant de commencer

  1. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

    Si vous sélectionnez un projet existant, vous devez sélectionner un projet répondant aux conditions suivantes :

    • Datastore n'est pas activé.
    • App Engine n'est pas activé.
    • Le projet n'inclut pas de base de données Firestore avec des règles de sécurité existantes. Vous allez remplacer les règles existantes par celles décrites dans ce document.
  2. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  3. Activer Identity Platform :
    1. Accédez à la page "Identity Platform Marketplace" dans la console Google Cloud.

      Accéder à la page "Identity Platform Marketplace"

    2. Cliquez sur Activer Identity Platform et attendez la fin de l'opération.
  4. Activez Firestore :
    1. Dans la console Google Cloud, ouvrez le menu situé sur la gauche, puis sélectionnez Firestore.
    2. Sélectionnez un mode Firestore. Cliquez sur Sélectionner le mode natif.
    3. Choisissez où stocker vos données. Sélectionnez la région la plus proche de votre position. Cliquez sur Create Database (Créer une base de données).

Une fois que vous avez terminé les tâches décrites dans ce document, vous pouvez éviter de continuer à payer des frais en supprimant les ressources que vous avez créées. Pour en savoir plus, consultez la section Effectuer un nettoyage.

Configurer Identity Platform

Pour activer l'authentification des utilisateurs dans Identity Platform, vous devez ajouter des fournisseurs d'identité.

Avant de configurer un fournisseur Google dans Identity Platform, vous devez configurer l'écran d'autorisation OAuth de Google. Les utilisateurs voient cet écran d'autorisation la première fois qu'ils se connectent à votre application Web. Dans la configuration de l'écran d'autorisation OAuth, vous pouvez définir des attributs tels que le nom de votre application, le logo de votre application et une adresse e-mail d'assistance.

  1. Dans la console Google Cloud, accédez à la page Fournisseurs d'identité.

    Accéder à la page "Fournisseurs d'identité"

  2. Cliquez sur Ajouter un fournisseur.
  3. Sélectionnez Google, puis, sur la page Nouveau fournisseur d'identité, cliquez sur le lien API et services. La page Identifiants s'ouvre dans un nouvel onglet. Ne fermez pas l'onglet précédent, car vous devez copier des valeurs depuis la page Identifiants vers la page Nouveau fournisseur d'identité.
  4. Sur la page Identifiants, cliquez sur les identifiants du Client Web (créé automatiquement par le service Google).
  5. Copiez la valeur de l'ID client, accédez à l'onglet de la page Nouveau fournisseur d'identité, et collez la valeur dans le champ ID client Web. Répétez cette étape pour copier la valeur du code secret du client dans le champ Code secret du client Web.
  6. Sur la page Nouveau fournisseur d'identité, cliquez sur Enregistrer.
  7. Revenez à la page Identifiants, puis cliquez sur Écran d'autorisation OAuth.
  8. Sélectionnez Externe, puis cliquez sur Créer.
  9. Sur la page Écran d'autorisation OAuth, ajoutez les informations suivantes :
    • Nom de l'application : Identity Platform Tutorial
    • Adresse e-mail d'assistance : sélectionnez votre adresse e-mail dans la liste déroulante.
  10. Cliquez sur Enregistrer.
  11. Sur la page Modifier l'enregistrement de l'application, ajoutez les informations suivantes :
    • Nom de l'application : Identity Platform Tutorial
    • Adresse e-mail d'assistance utilisateur : sélectionnez votre adresse e-mail dans la liste déroulante.
    • Adresses e-mail : saisissez votre adresse e-mail.
  12. Cliquez sur Enregistrer et continuer.
  13. Sur les pages Champs d'application et Informations facultatives, cliquez sur Enregistrer et continuer.
  14. Sur la page Résumé, cliquez sur Revenir au tableau de bord.

Configurer Firestore

La nouvelle base de données Firestore que vous avez créée est actuellement vide. Elle possède également un ensemble de règles de sécurité par défaut qui autorisent tous les utilisateurs à effectuer des opérations de lecture sur la base de données. Ces règles par défaut empêchent toute opération d'écriture sur la base de données. Dans les étapes suivantes, vous allez ajouter des données à la base de données, puis mettre à jour les règles de sécurité pour limiter les requêtes de lecture aux utilisateurs autorisés.

Créer des données test dans Firestore

Dans cette procédure, vous testez les règles de sécurité en interrogeant les collections Firestore à partir d'une application Web.

Commencez par créer plusieurs documents pour vous aider à tester les règles de sécurité Firestore. Les noms de collections et de champs sont sensibles à la casse. Utilisez des noms en minuscules pour la collection et les champs afin d'éviter tout échec de l'application Web lorsqu'elle envoie une requête à Firestore.

  1. Accédez à la page Firestore de la console Google Cloud.
  2. Cliquez sur Démarrer la collection.
  3. Dans le champ ID de collection, saisissez customers.
  4. Créez un document avec les informations suivantes :

    ID du document : [email protected]

    fieldName Type de champ Valeur du champ
    name String Bob
    notre société String
    
    ExampleOrganization
  5. Cliquez sur Enregistrer et ajouter.

  6. Cliquez sur Effacer les valeurs des champs.

  7. Saisissez les informations suivantes :

  8. ID du document : votre adresse e-mail

    fieldName Type de champ Valeur du champ
    name String Votre nom
    notre société String Le nom de votre entreprise
  9. Cliquez sur Enregistrer.

Créer des règles de sécurité Firestore

Les règles de sécurité Firestore peuvent être évaluées à l'aide des métadonnées d'authentification de l'utilisateur, des données des requêtes entrantes et des données existantes dans votre base de données.

Dans cette procédure, vous créez une règle de sécurité pour Firestore basée sur l'adresse e-mail et le nom du fournisseur de l'utilisateur connecté.

Utilisez la console Firebase pour gérer les règles de sécurité Firestore.

  1. Ouvrez la console Firebase, puis cliquez sur votre projet.
  2. Cliquez sur Firestore dans la partie gauche de l'écran.
  3. Sur la page Firestore, cliquez sur l'onglet Règles.
  4. Si vous choisissez d'utiliser un projet existant contenant une base de données Firestore avec des règles de sécurité, et que vous prévoyez de nettoyer le projet lorsque vous avez terminé les procédures de ce document, notez vos règles de sécurité existantes.
  5. Remplacez les règles existantes par la règle suivante :

    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
        }
      }
    }
    

    Cette règle accorde une autorisation en lecture seule pour la collection customers. La règle vérifie que vous vous êtes bien connecté via le fournisseur de connexion Google que vous avez configuré dans Identity Platform. Cela garantit également que vous ne pouvez récupérer que les documents dont le numéro client correspond à votre adresse e-mail.

  6. Cliquez sur Publier.

Configurer l'environnement de test

Pour tester vos règles de sécurité Firestore, commencez par créer une application Web qui oblige les utilisateurs à se connecter. L'application Web est disponible sur GitHub et téléchargée dans un environnement Cloud Shell, où vous pouvez tester l'application. Une fois l'utilisateur connecté, l'application Web lit les documents de Firestore et affiche leur contenu.

Configurer l'application Web

  1. Accédez à la page "Fournisseurs Identity Platform".

    Accéder à la page "Fournisseurs Identity Platform"

  2. Sur la partie droite de la page, cliquez sur Informations sur la configuration de l'application.
  3. Copiez les valeurs répertoriées à côté de apiKey et authDomain dans votre presse-papiers, puis cliquez sur Fermer.
  4. Cliquez sur Google Cloud en haut de la page et copiez l'ID de projet de la fiche Informations sur le projet.
  5. Cliquez sur Ouvrir dans Cloud Shell pour ouvrir Cloud Shell, clonez le dépôt GitHub, puis ouvrez le fichier config.js. Lorsque la boîte de dialogue "Ouvrir dans Cloud Shell" s'affiche, cliquez sur Confirmer.

    Ouvrir dans Cloud Shell

  6. Dans le fichier config.js, remplacez les espaces réservés [API_KEY], [AUTH_DOMAIN] et [PROJECT_ID] par les valeurs copiées à l'étape précédente. Votre code injecte ces valeurs dans l'URL et le corps des messages qu'il crée lorsqu'il envoie des requêtes à Identity Platform.

Enregistrer le gestionnaire d'authentification personnalisée

Lorsque les utilisateurs accèdent à votre application Web, ils sont redirigés pour se connecter en utilisant Google en tant que fournisseur d'identité. Une fois que l'utilisateur s'est connecté à Google, Google renvoie une réponse de redirection (302) au gestionnaire d'authentification avec le jeton de l'utilisateur, comme illustré dans le schéma de l'architecture. Dans OAuth 2.0, vous devez enregistrer à l'avance chaque URL de redirection dans la configuration pour le fournisseur, afin d'empêcher le fournisseur d'envoyer votre jeton vers une destination inconnue. La page Enregistrement de l'URL de redirection sur le site Web OAuth 2.0 explique les raisons de cette restriction.

Au cours de cette étape, vous allez mettre à jour la liste des URL de redirection autorisées pour approuver les gestionnaires d'authentification utilisés dans ce document.

Cette liste fait partie de la configuration du client Google OAuth 2.0, c'est-à-dire de la page à partir de laquelle vous avez copié l'ID client et le code secret du client à partir de la configuration d'Identity Platform.

Dans cette architecture, vous utilisez deux gestionnaires d'authentification différents :

  • Un gestionnaire d'authentification hébergé par Identity Platform.
  • Un gestionnaire d'authentification personnalisé hébergé par l'application Web.

Le gestionnaire d'authentification hébergé par Identity Platform est accessible via le point de terminaison suivant, qui est géré par Google : https://[YOUR_PROJECT_ID].firebaseapp.com/__/auth/handler

Pour utiliser ce gestionnaire, vous n'avez pas besoin de mettre à jour la liste des URL autorisées dans les paramètres du client pour Google OAuth 2.0. Lorsque vous avez activé Identity Platform plus tôt dans ce document, il a ajouté automatiquement l'URL à la liste des URL autorisées.

Si vous utilisez le SDK client Identity Platform, le SDK utilise ce gestionnaire d'authentification intégré. Le gestionnaire d'authentification pour Identity Platform exige que votre application Web utilise ce SDK, car celui-ci échange des objets d'état avec le gestionnaire. Le SDK indique par exemple au gestionnaire vers quelle page rediriger les utilisateurs après s'être connectés avec succès à Identity Platform.

Pour le gestionnaire d'authentification personnalisé hébergé par l'application Web, lorsque vous utilisez les API REST Identity Platform directement à partir de JavaScript, nous vous recommandons de mettre en œuvre et d'héberger votre propre gestionnaire d'authentification plutôt que le SDK.

Ce document décrit un exemple de gestionnaire d'authentification qui gère le processus de connexion à Identity Platform lorsqu'il reçoit le jeton utilisateur de Google. Vous devez ajouter l'URL du gestionnaire personnalisé à la liste des URL autorisées dans les paramètres de votre client Google OAuth 2.0.

Dans ce document, vous allez exécuter l'application Web à partir de Cloud Shell. Après avoir démarré l'application Web, recherchez le nom d'hôte de votre instance Cloud Shell et mettez à jour la configuration du fournisseur en conséquence.

  1. Exécutez l'application Web à partir de Cloud Shell :

    npm install
    node app.js
    
  2. Attendez que la sortie suivante apparaisse : Example app listening on port 8080!

  3. Cliquez sur l'icône Aperçu sur le Web, puis sur Prévisualiser sur le port 8080. Attendez que le nouvel onglet affiche la page Web et copiez la valeur sous URL du gestionnaire d'authentification (pour le client Google OAuth 2.0).

  4. Accédez à la page Identifiants.
    Accéder à la page "Identifiants"

  5. Sur la page Identifiants, cliquez sur Client Web (créé automatiquement par le service Google).

  6. Sur la page URI de redirection autorisés, cliquez sur Ajouter un URI, puis collez l'URL copiée précédemment.

  7. Cliquez sur Enregistrer et quittez l'application Web en cours d'exécution.

Autoriser le domaine de l'application Web

Lorsque vous utilisez le gestionnaire d'authentification Identity Platform, il vous redirige vers l'application Web, avec vos informations utilisateur et vos jetons. Pour empêcher l'envoi de vos informations vers un domaine non autorisé, vous devez autoriser le domaine sur lequel votre application Web est exécutée.

  1. Revenez à la page Web par défaut de l'application Web et copiez la valeur sous Nom d'hôte (pour les domaines Identity Platform autorisés).
  2. Accédez à la page "Paramètres" d'Identity Platform.

    Accéder à la page "Paramètres" d'Identity Platform

  3. Cliquez sur l'onglet Sécurité, puis sur Ajouter un domaine.
  4. Collez le domaine que vous avez copié, cliquez sur Ajouter, puis sur Enregistrer.
  5. Assurez-vous que l'application Web s'exécute toujours dans Cloud Shell. Vous en aurez besoin pour la prochaine tâche.

Se connecter à Identity Platform avec votre identité Google

Le schéma suivant développe le schéma de l'architecture de haut niveau au début de ce guide. Ce schéma présente les détails du processus d'authentification décrit dans ce document afin de montrer le flux chronologique des événements. Les événements commencent lorsque l'utilisateur clique sur un bouton de connexion et se terminent lorsque l'application Web récupère des données depuis Firestore, à l'aide de l'identité de l'utilisateur :

Architecture de haut niveau

  1. Un utilisateur de votre application Web clique sur Se connecter avec Google dans l'application Web.
  2. L'application Web interroge Identity Platform pour obtenir l'URL de connexion du fournisseur d'identité choisi (Google dans ce cas).
  3. L'application Web redirige l'utilisateur vers la page de connexion de votre fournisseur d'identité, avec une URL de rappel pointant vers le gestionnaire d'authentification.
  4. Sur la page de connexion du fournisseur, l'utilisateur saisit ses identifiants et accorde l'autorisation requise par l'application Web.
  5. Une fois l'utilisateur connecté, le fournisseur génère un jeton et envoie une redirection vers l'URL de rappel précédemment fournie.
  6. Le gestionnaire d'authentification reçoit le jeton émis par Google et l'envoie à Identity Platform pour connecter l'utilisateur. Identity Platform valide le jeton, connecte l'utilisateur et renvoie un jeton d'ID et un jeton d'actualisation Identity Platform émis avec les informations de l'utilisateur. Lorsque Identity Platform connecte un utilisateur pour la première fois, il crée un profil utilisateur correspondant dans sa base de données. Les informations de compte mises à disposition par Google permettent de renseigner le profil de l'utilisateur.
  7. Une fois que vous êtes connecté à Identity Platform, le gestionnaire vous redirige vers l'application Web, avec les nouveaux jetons obtenus d'Identity Platform.
  8. Pour envoyer des requêtes à Firestore, l'application Web associe le jeton d'ID de l'utilisateur à chaque requête Firestore. Les règles de sécurité Firestore stipulent que Firestore traite toute requête sans jeton d'ID en tant que requête anonyme, et celle-ci sera donc refusée.
  9. Les jetons d'identification émis par Identity Platform expirent au bout d'une heure. Si le jeton d'ID expire, l'application Web utilise le jeton d'actualisation mis en cache pour récupérer un nouveau jeton d'ID auprès d'Identity Platform.

L'exemple d'application Web montre deux manières d'interagir avec Identity Platform et Firestore.

La première méthode consiste à utiliser l'API REST Identity Platform :

  • Cette technique utilise un code personnalisé qui appelle les API REST Identity Platform à l'aide de JavaScript.
  • Les appels d'API sont mis en œuvre dans le fichier site/identity-platform-auth-helper.js. Le gestionnaire d'authentification est mis en œuvre dans le fichier views/auth-handler.ejs.
  • L'outil d'aide et le gestionnaire échangent les objets d'état pour activer la redirection vers l'application Web après votre connexion.

La deuxième méthode consiste à utiliser le SDK client Identity Platform :

  • Avec cette technique, le SDK gère le processus de connexion.
  • Le SDK met en œuvre tous les appels d'API requis et expose un ensemble de fonctions au développeur pour contrôler le flux de connexion à lancer.

Se connecter avec des API REST Identity Platform

Deux principaux appels d'API contrôlent le flux de connexion avec Google en tant que fournisseur d'identité.

Les deux principaux appels d'API qui contrôlent le flux de connexion avec Google en tant que fournisseur

  • Obtenir l'URL et l'identifiant du fournisseur. La méthode accounts.createAuthUri renvoie une URL d'autorisation pour le fournisseur d'identité donné. L'application Web accède ensuite à l'URL d'autorisation renvoyée pour lancer le processus de connexion avec le fournisseur d'identité sélectionné (par exemple, Google).

    L'extrait de code suivant montre comment appeler cette 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);
      });
    };
  • Se connecter à Identity Platform à l'aide d'un jeton émis par Google. La méthode accounts.signInWithIdp connecte l'utilisateur à Identity Platform à l'aide de la réponse d'autorisation du fournisseur d'identité. L'API répond à cette requête avec un nouveau jeton, émis par Identity Platform. L'application Web appelle cette API après avoir reçu une réponse d'autorisation du fournisseur d'identité. L'extrait de code suivant montre comment appeler cette 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);
      });
    }

    La valeur du champ postBody a des formats différents, en fonction du fournisseur d'identité sélectionné et du protocole d'autorisation qu'il utilise. Ce code gère le fournisseur d'identité Google avec son jeton OpenID Connect (OIDC) et les fournisseurs d'identité basés sur SAML avec les réponses SAML fournies. Si vous utilisez d'autres types de jetons d'autorisation, tels que des jetons d'accès OAuth 2.0 ou OAuth 1.0, reportez-vous à la documentation de l'API de votre fournisseur.

Lorsqu'un utilisateur se connecte à votre application Web, celle-ci peut envoyer des requêtes à Firestore.

Flux d'événements lorsque l'application Web envoie une requête à Firestore

Avant que le code ne puisse déclencher une requête pour les API REST Firestore, il ajoute le jeton d'ID émis et signé par Identity Platform à la requête. L'extrait de code suivant montre comment créer la requête :

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 fonction IdentityPlatformAuthHelper.getIdToken() renvoie un jeton d'ID valide sous la forme d'un jeton Web JSON (JWT), en récupérant un jeton mis en cache par le navigateur. Si le jeton a déjà expiré, la fonction le renouvelle en appelant l'API Identity Platform afin d'échanger un jeton d'actualisation contre un nouveau jeton d'ID.

L'extrait de code suivant montre comment vérifier si le jeton d'ID existant est toujours valide ou s'il est arrivé à expiration, et comment l'actualiser si nécessaire en appelant 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);
  });
}

Pour vous connecter à Identity Platform à l'aide de votre identité Google, procédez comme suit :

  1. Revenez à l'onglet affichant la page par défaut de l'application Web. Si vous avez déjà fermé cet onglet, revenez à la page Cloud Shell, cliquez sur Aperçu sur le Web, puis sur Prévisualiser sur le port 8080. Attendez que le nouvel onglet affiche la page Web.
  2. Modifiez l'adresse dans le navigateur pour afficher la page customer-info-with-api.html. La nouvelle URL est au format suivant : https://random_prefix-devshell.appspot.com/customer-info-with-api.html
  3. Cliquez sur Se connecter avec Google et connectez-vous avec vos identifiants. Une fois connecté, une zone de texte apparaît avec votre adresse e-mail.

    Si vous souhaitez décoder le jeton JWT pour afficher les informations utilisateur fournies par Identity Platform et Google, procédez comme suit : Autrement, passez directement à l'étape suivante.

    Les informations sur l'utilisateur se trouvent dans la partie charge (deuxième partie) du jeton JWT, et sont encodées en base64. Pour décoder la deuxième partie du jeton JWT et imprimer les informations dans un fichier JSON à l'aide de jq, exécutez la commande suivante dans Cloud Shell :

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

    Continuez à rechercher d'autres documents dans Firestore.

  4. Cliquez sur Informations sur le client. Votre nom et celui de votre entreprise s'affichent, tels que vous les avez saisis dans la base de données Firestore.

  5. Remplacez l'adresse e-mail par [email protected], puis cliquez sur Se connecter avec Google. La réponse cette fois est le message d'erreur suivant :

    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. Ne fermez pas la page Web. Vous en aurez besoin pour la procédure suivante.

Se connecter à l'aide du SDK client Identity Platform

Au lieu de créer manuellement les requêtes dans Identity Platform, vous pouvez utiliser le SDK client Identity Platform. Le SDK gère le processus de connexion et fournit des fonctions permettant de contrôler le flux de connexion, tel que le fournisseur à utiliser, ou l'utilisation d'une redirection ou d'un pop-up.

Pour utiliser le SDK client Identity Platform, vous devez inclure plusieurs fichiers de script dans votre page HTML. L'extrait de code suivant indique les scripts dont vous avez besoin :

<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>

L'extrait de code suivant montre comment utiliser le SDK pour vous connecter avec le fournisseur 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 fonction firebase.auth().signInWithRedirect() lance le processus de connexion dans la même fenêtre de navigateur, en redirigeant l'utilisateur vers la page de connexion du fournisseur. L'utilisation de GoogleAuthProvider indique à la fonction de lancer le flux de connexion Google.

Vous pouvez remplacer le comportement de redirection par un comportement de type pop-up en appelant la fonction signInWithPopup à la place.

Pour utiliser d'autres fournisseurs d'authentification, ajoutez n'importe quel type qui met en œuvre l'interface firebase.auth.AuthProvider. Pour vous assurer que tous les paramètres requis sont corrects, consultez la documentation du fournisseur sélectionné.

La fonction firebase.auth().onAuthStateChanged est un observateur qui se déclenche lors de la connexion et de la déconnexion. Lors de la connexion, le code de l'application Web renseigne la page Web avec les informations issues de l'objet User et masque le bouton de connexion. Lors de la déconnexion, le code efface la page Web et affiche à nouveau le bouton de connexion.

Le SDK client Identity Platform s'intègre au SDK Firestore. À chaque requête, le SDK Firestore associe un jeton d'ID valide en le récupérant depuis le SDK client Identity Platform. Le SDK du client Identity Platform est responsable de l'actualisation du jeton ID lorsqu'il expire.

L'extrait de code suivant montre comment interroger Firestore à l'aide du SDK 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());
  });
}

Notez que vous n'avez pas à écrire de code pour ajouter le jeton d'ID à la requête. Le SDK Firestore et le SDK client Identity Platform gèrent le processus d'authentification.

Procédez comme suit pour vous connecter à Identity Platform à l'aide de votre identité Google, puis interroger Firestore :

  1. Si vous avez déjà fermé l'onglet d'application Web approprié, revenez à la page Cloud Shell, cliquez sur Aperçu sur le Web, puis sur Prévisualiser sur le port 8080. Attendez que le nouvel onglet affiche la page Web.
  2. Modifiez l'adresse dans le navigateur pour afficher la page customer-info-with-sdk.html. La nouvelle URL est au format suivant : https://random_prefix-devshell.appspot.com/customer-info-with-sdk.html
  3. Cliquez sur Se connecter avec Google et connectez-vous avec vos identifiants. Une fois connecté, une zone de texte apparaît avec votre adresse e-mail.
  4. Cliquez sur Informations sur le client. Votre nom et celui de votre entreprise s'affichent, tels que vous les avez saisis dans la base de données Firestore.
  5. Remplacez l'adresse e-mail par [email protected], puis cliquez sur Se connecter avec Google. La réponse cette fois est un message d'erreur :

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

    Pour en savoir plus sur l'utilisation de JavaScript pour interroger Firestore, consultez la documentation de Firestore.

Résoudre les problèmes dans l'application Web

Découvrez les étapes de dépannage qui pourraient vous être utiles si vous rencontrez les problèmes suivants lors de l'exécution de l'application Web.

Erreurs lors de la navigation dans l'application Web

Erreur Remarques
L'un des messages d'erreur suivants s'affiche :

Error:Could not connect to Cloud Shell on port 8080

Error:No active Cloud Shell
Assurez-vous que Cloud Shell est ouvert et que l'application Web s'exécute, comme expliqué dans la section Enregistrer le gestionnaire d'authentification personnalisé. Si vous ouvrez une nouvelle session Cloud Shell, remplacez le répertoire de travail par le répertoire de l'application Web, avant d'exécuter l'application Web :

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

Après avoir exécuté l'application Web, vérifiez que le résultat suivant s'affiche :

Example app listening on port 8080!

Erreurs lors de la connexion à Google

Erreur Remarques
Rien ne se passe lorsque vous cliquez sur Se connecter avec Google. Le code d'erreur suivant s'affiche :

Cannot GET /undefined
Assurez-vous d'avoir défini les variables apiKey et authDomain dans le fichier config.js, comme expliqué dans la section Configurer l'application Web.
Le message d'erreur suivant s'affiche sur la page de connexion Google :

Authorization Error - Error 400: redirect_uri_mismatch
L'URL de redirection envoyée à Google ne correspond pas à la liste des URL autorisées pour le client OAuth. Assurez-vous d'avoir configuré les URI de redirection autorisés, comme expliqué dans la section Enregistrer le gestionnaire d'authentification personnalisé.
Lorsque vous vous connectez à Google avec le SDK Identity Platform, le message d'erreur suivant s'affiche :

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
Cette erreur peut se produire si le domaine utilisé par Cloud Shell n'existe pas dans la liste des domaines autorisés pour Identity Platform. Pour vérifier que le nom de domaine a bien été ajouté à la liste des domaines autorisés, suivez la procédure décrite dans la section Autoriser le domaine de l'application Web.

Erreurs lors de la récupération des informations sur le client

Erreur Remarques
L'un des messages d'erreur suivants peut s'afficher :

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

Error: Missing or insufficient permissions
Il est possible que les règles de sécurité Firestore n'aient pas réussi à valider le jeton envoyé à Firestore. Assurez-vous que les règles de sécurité Firestore sont correctement configurées, comme décrit dans la section Créer des règles de sécurité Firestore.
L'un des messages d'erreur suivants peut s'afficher :

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
Assurez-vous d'avoir défini la propriété projectId dans le fichier config.js, comme expliqué dans la section Configurer l'application Web.

Nettoyer

Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et supprimez les ressources individuelles.

  1. Dans la console Google Cloud, accédez à la page Gérer les ressources.

    Accéder à la page Gérer les ressources

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

Supprimer des ressources individuelles

  1. Dans Cloud Shell, arrêtez l'application Web en appuyant sur Ctrl+C.
  2. Supprimez le répertoire du dépôt cloné :

    rm -rf "$HOME"/cloudshell_open/securing-cloud-firestore-with-identity-platform
    
  3. Accédez à la page "Paramètres" d'Identity Platform.

    Accéder à la page "Paramètres" d'Identity Platform

  4. Cliquez sur l'onglet Sécurité, supprimez le domaine que vous avez ajouté précédemment, puis cliquez sur Enregistrer.

  5. Accédez à la page "Fournisseurs d'identité"

    Accéder à la page "Fournisseurs d'identité"

  6. Supprimez le fournisseur Google précédemment ajouté.

  7. Accédez à API et services puis à la page Identifiants.

    Accéder à la page Identifiants

  8. Sur la page "Identifiants", cliquez sur le client Web (créé automatiquement par le service Google).

  9. Sur la page URI de redirection autorisés, supprimez l'URL que vous avez précédemment collée, puis cliquez sur Enregistrer.

  10. Ouvrez la console Firebase, puis cliquez sur votre projet dans le volet de navigation de la console.

  11. Sélectionnez l'option Base de données dans le menu Développer sur la gauche.

  12. Sur la page Base de données, cliquez sur l'onglet Règles.

  13. Remplacez les règles de sécurité actuelles par celles que vous aviez avant de commencer le document, puis cliquez sur Publier.

  14. Accédez à la page Firestore de la console Google Cloud.

  15. Cliquez sur le menu à gauche de la collection clients, puis cliquez sur Supprimer la collection.

  16. Dans la fenêtre pop-up de confirmation de suppression, saisissez customers dans le champ ID de collection, puis cliquez sur Supprimer.

Étapes suivantes

Découvrez des architectures de référence, des schémas et des bonnes pratiques concernant Google Cloud. Consultez notre Centre d'architecture cloud.