Envoyer une requête authentifiée depuis une application JavaScript

Cette page explique comment envoyer une requête authentifiée depuis une application JavaScript s'exécutant localement vers une API REST créée à l'aide de Cloud Endpoints Frameworks. L'application JavaScript indique comment utiliser Google Sign-In et envoyer un jeton d'ID Google dans la requête d'authentification de l'utilisateur. Lorsque l'application JavaScript envoie la requête, Endpoints Frameworks authentifie l'utilisateur avant de transmettre la requête au code backend exécuté dans l'environnement standard App Engine.

Prerequisites

Pour exécuter l'exemple d'application JavaScript :

  • Recherchez l'ID du projet Google Cloud que vous avez créé pour l'exemple d'API, car vous devez l'ajouter à l'exemple de code JavaScript. Si vous avez besoin d'aide pour trouver l'ID de projet, consultez la page Répertorier les projets.

  • Vous avez besoin d'un serveur Web sur votre ordinateur local pour traiter l'exemple de fichier index.html contenant le code JavaScript. Cette page inclut des étapes pour exécuter un serveur simple à l'aide de Python, mais vous pouvez utiliser n'importe quel serveur Web.

Télécharger l'exemple de code client JavaScript

  1. Clonez l'exemple sur votre ordinateur local :

    git clone https://github.com/GoogleCloudPlatform/web-docs-samples
    
  2. Accédez au répertoire contenant le client JavaScript :

    cd web-docs-samples/endpoints-frameworks
    

Créer des ID client OAuth 2.0

Pour configurer l'exemple pour l'authentification, vous devez configurer un ID client OAuth 2.0 dans l'exemple de code JavaScript et dans le code backend. L'application JavaScript utilise l'ID client pour obtenir un jeton d'ID Google auprès du serveur OAuth 2.0 de Google et envoie ce jeton dans la requête. Endpoints Frameworks utilise l'ID client pour authentifier le jeton d'ID envoyé par l'application JavaScript dans la requête.

Pour créer un ID client, procédez comme suit :

  1. Dans Google Cloud Console, accédez à la page "Identifiants".

    Accéder à la page "Identifiants"

  2. Dans la liste des projets, sélectionnez le projet que vous avez créé pour l'exemple d'API.

  3. Cliquez sur le bouton Créer des identifiants, puis sélectionnez ID client OAuth. Si vous créez un ID client pour ce projet pour la première fois, suivez les sous-étapes pour définir un nom de produit sur l'écran de consentement. Sinon, passez à l'étape suivante.

    1. Cliquez sur le bouton Configurer l'écran d'autorisation.
    2. Saisissez un nom dans le champ Nom de l'application.
    3. Cliquez sur Enregistrer.
  4. Sous Type d'application, cliquez sur Application Web.

  5. Dans le champ Origines JavaScript autorisées, saisissez les informations suivantes :

    http://localhost:8080
    
  6. Cliquez sur Create (Créer).

  7. Copiez votre ID client. Votre ID client complet ressemble à ce qui suit, mais il est unique à l'application Web de votre projet :

    271473851874-mtll5dk2vultovbtilt31hakqbinpuvd.apps.googleusercontent.com

Pour en savoir plus sur la création d'ID clients, consultez la page Configurer OAuth 2.0.

Configurer et redéployer le code backend

Pour que Cloud Endpoints Frameworks puisse authentifier la requête envoyée à partir de l'application JavaScript, vous devez ajouter l'ID client que vous venez de créer dans l'exemple de code, puis redéployer le document OpenAPI mis à jour et le code backend de l'application.

La procédure suivante suppose que vous avez déjà déployé l'exemple d'API à partir de la page Premiers pas avec Endpoints Frameworks pour App Engine. Avant de lancer la procédure suivante, assurez-vous d'obtenir une réponse positive lorsque vous envoyez une requête à l'API, comme décrit dans la section Envoyer une requête à l'API.

Pour configurer le code backend et le redéployer, procédez comme suit :

  1. Dans le répertoire dans lequel vous avez cloné le dépôt java-docs-samples, accédez au répertoire qui contient l'exemple Java :

    cd YOUR_WORKING_DIRECTORY/java-docs-samples/appengine-java8/endpoints-v2-backend
    
  2. Ouvrez le fichier src/main/java/com/example/echo/Echo.java dans un éditeur de texte.

  3. Dans l'annotation @ApiMethod de la méthode getUserEmail, remplacez YOUR_OAUTH_CLIENT_ID dans les attributs audiences et clientIds par l'ID client que vous avez créé.

    @ApiMethod(
        httpMethod = ApiMethod.HttpMethod.GET,
        authenticators = {EspAuthenticator.class},
        audiences = {"YOUR_OAUTH_CLIENT_ID"},
        clientIds = {"YOUR_OAUTH_CLIENT_ID"}
    )
    public Email getUserEmail(User user) throws UnauthorizedException {
      if (user == null) {
        throw new UnauthorizedException("Invalid credentials");
      }
    
      Email response = new Email();
      response.setEmail(user.getEmail());
      return response;
    }
  4. Enregistrez le fichier Echo.java.

  5. Nettoyez votre projet, puis compilez votre API :

    Maven

    mvn clean package

    Gradle

          gradle clean
          gradle build
  6. Générez à nouveau le document OpenAPI openapi.json afin qu'il contienne l'ID client.

    Maven

    mvn endpoints-framework:openApiDocs

    Gradle

    gradle endpointsOpenApiDocs
  7. Assurez-vous que la CLI Google Cloud (gcloud) est autorisée à accéder à vos données et services sur Google Cloud:

    gcloud auth login
    
  8. Définissez le projet par défaut pour la CLI Google Cloud. Remplacez YOUR_PROJECT_ID par l'ID de projet que vous avez créé pour l'exemple d'API :

    gcloud config set project YOUR_PROJECT_ID
    
  9. Déployez le document OpenAPI mis à jour :

    gcloud endpoints services deploy target/openapi-docs/openapi.json
    
  10. Attendez que la commande se termine, puis redéployez votre application comme suit :

    Maven

    mvn appengine:deploy

    Gradle

    gradle appengineDeploy

Configurer le code JavaScript

Pour configurer le code JavaScript, procédez comme suit :

  1. Dans le répertoire web-docs-samples/endpoints-frameworks, ouvrez le fichier main.js dans un éditeur de texte.
  2. Dans la fonction initGoogleAuth, remplacez YOUR_CLIENT_ID par l'ID client que vous avez créé.

    function initGoogleAuth (clientId = 'YOUR_CLIENT_ID') {
      gapi.auth2.init({
        client_id: clientId,
        scope: 'https://www.googleapis.com/auth/userinfo.email'
      }).then(() => {
        document.getElementById('sign-in-btn').disabled = false;
      }).catch(err => {
        console.log(err);
      });
    }
  3. Dans la fonction sendSampleRequest, remplacez YOUR_PROJECT_ID par l'ID de projet que vous avez créé pour l'exemple d'API.

    function sendSampleRequest (projectId = 'YOUR_PROJECT_ID') {
      var user = gapi.auth2.getAuthInstance().currentUser.get();
      var idToken = user.getAuthResponse().id_token;
      var endpoint = `https://${projectId}.appspot.com/_ah/api/echo/v1/email`;
      var xhr = new XMLHttpRequest();
      xhr.open('GET', endpoint + '?access_token=' + encodeURIComponent(idToken));
      xhr.onreadystatechange = function () {
        if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
          window.alert(xhr.responseText);
        }
      };
      xhr.send();
    }

Envoyer une requête authentifiée

  1. Dans le répertoire dans lequel vous avez cloné le dépôt web-docs-samples, accédez au répertoire qui contient l'exemple JavaScript :

    cd YOUR_WORKING_DIRECTORY/web-docs-samples/endpoints-frameworks
    
  2. Démarrez votre serveur Web pour diffuser index.html sur le port 8080. L'exemple suivant utilise le serveur simple de Python:

    python -m http.server 8080
    
  3. Dans votre navigateur, saisissez localhost:8080.

    L'application JavaScript affiche deux boutons.

    Connexion

  4. Cliquez sur Se connecter. La page Se connecter avec Google s'affiche.

  5. Une fois connecté, cliquez sur le bouton Send sample request (Envoyer l'exemple de requête). La première fois que vous envoyez une requête, vous pouvez rencontrer un délai d'environ 20 secondes au démarrage d'App Engine. Endpoints Frameworks intercepte les requêtes et utilise l'ID client que vous avez configuré dans le code du backend pour les authentifier. Si l'authentification réussit, les événements suivants se produisent :

    1. Endpoints Frameworks transmet la requête à l'exemple de backend exécuté sur App Engine.

    2. Dans le code du backend, la méthode getUserEmail renvoie l'adresse e-mail du compte utilisateur avec lequel vous vous êtes connecté.

    3. Le client JavaScript affiche une boîte de dialogue avec l'adresse e-mail.

Présentation du client JavaScript

Le client JavaScript utilise Google Sign-In, qui gère le flux OAuth 2.0. Cette section offre un aperçu du code client JavaScript.

Configurer Auth

  1. Chargez la bibliothèque de la plate-forme d'API Google pour créer l'objet gapi :

      <script src="https://apis.google.com/js/platform.js?onload=loadAuthClient" async defer></script>
    </head>
  2. Une fois la bibliothèque de la plate-forme d'API Google chargée, chargez la bibliothèque auth2 :

    function loadAuthClient () {
      gapi.load('auth2', initGoogleAuth);
    }
  3. Initialisez l'objet GoogleAuth :

    function initGoogleAuth (clientId = 'YOUR_CLIENT_ID') {
      gapi.auth2.init({
        client_id: clientId,
        scope: 'https://www.googleapis.com/auth/userinfo.email'
      }).then(() => {
        document.getElementById('sign-in-btn').disabled = false;
      }).catch(err => {
        console.log(err);
      });
    }

Lorsque vous initialisez l'objet GoogleAuth, vous le configurez avec votre ID client OAuth 2.0 et toute autre option que vous souhaitez spécifier. En règle générale, vous spécifiez le champ d'application d'accès. Les niveaux d'accès permettent à votre application de demander uniquement l'accès aux ressources dont elle a besoin, tout en permettant aux utilisateurs de contrôler le l'accès qu'ils accordent à votre application. Avant de commencer la mise en œuvre de l'autorisation OAuth 2.0, nous vous recommandons d'identifier les champs d'application pour lesquels votre application a besoin d'une autorisation d'accès. Cet exemple demande l'accès au champ d'application https://www.googleapis.com/auth/userinfo.email, qui permet d'afficher l'adresse e-mail de l'utilisateur.

Se connecter

Une fois l'objet GoogleAuth initialisé, vous pouvez inviter l'utilisateur à se connecter en appelant la fonction signIn de l'objet GoogleAuth :

function signIn () {
  gapi.auth2.getAuthInstance().signIn().then(() => {
    document.getElementById('sign-in-btn').hidden = true;
    document.getElementById('sign-out-btn').hidden = false;
    document.getElementById('send-request-btn').disabled = false;
  }).catch(err => {
    console.log(err);
  });
}

Envoyer une requête avec le jeton d'ID

Une fois l'utilisateur connecté, envoyez une requête avec un en-tête d'autorisation contenant le jeton d'ID de l'utilisateur :

function sendSampleRequest (projectId = 'YOUR_PROJECT_ID') {
  var user = gapi.auth2.getAuthInstance().currentUser.get();
  var idToken = user.getAuthResponse().id_token;
  var endpoint = `https://${projectId}.appspot.com/_ah/api/echo/v1/email`;
  var xhr = new XMLHttpRequest();
  xhr.open('GET', endpoint + '?access_token=' + encodeURIComponent(idToken));
  xhr.onreadystatechange = function () {
    if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
      window.alert(xhr.responseText);
    }
  };
  xhr.send();
}

Étapes suivantes