> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Comment sécuriser une API Google Cloud Endpoints avec Auth0.

# Sécuriser Google Cloud Endpoints avec Auth0

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

[Google Cloud Endpoints (GCE)](https://cloud.google.com/endpoints/) est un système de gestion d’API qui offre des fonctionnalités pour vous aider à créer, à maintenir et à sécuriser vos API. GCE utilise [OpenAPI](https://www.openapis.org/) pour définir les points de terminaison, les données d’entrée et de sortie, les erreurs et la description de sécurité de votre API.

Pour en savoir plus sur la spécification OpenAPI, consultez le dépôt [OpenAPI Specification](https://github.com/OAI/OpenAPI-Specification) sur GitHub.

Ce tutoriel explique comment sécuriser Google Cloud Endpoints avec Auth0.

<div id="prerequisites">
  ## Prérequis
</div>

Avant de commencer, vous devez disposer d'une API GCE déployée. Si vous n'avez pas encore créé d'API, suivez le [guide de démarrage rapide de Cloud Endpoints](https://cloud.google.com/endpoints/docs/quickstart-endpoints) dans la documentation de Google.

Ce guide de démarrage rapide vous montrera comment créer une API GCE simple avec un seul point de terminaison, `/airportName`, qui renvoie le nom d'un aéroport à partir de son [code IATA](https://en.wikipedia.org/wiki/IATA_airport_code) à trois lettres.

<AuthCodeGroup>
  ```bash cURL lines theme={null}
  curl --request GET \
    --url 'https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO'
  ```

  ```csharp C# lines theme={null}
  var client = new RestClient("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO");
  var request = new RestRequest(Method.GET);
  IRestResponse response = client.Execute(request);
  ```

  ```go Go lines theme={null}
  package main

  import (
  	"fmt"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO"

  	req, _ := http.NewRequest("GET", url, nil)

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java lines theme={null}
  HttpResponse<String> response = Unirest.get("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")
    .asString();
  ```

  ```javascript Node.JS lines theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'GET',
    url: 'https://%7ByourGceProject%7D.appspot.com/airportName',
    params: {iataCode: 'SFO'}
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP lines theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python lines theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  conn.request("GET", "%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby lines theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Get.new(url)

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

<div id="define-the-api-in-auth0">
  ## Définir l’API dans Auth0
</div>

Accédez à [Auth0 Dashboard > Applications > APIs](https://manage.auth0.com/#/apis) et créez une nouvelle API.

<Frame>
  <img src="https://mintcdn.com/translations/c0RQ9V0YAcT0-8l5/docs/images/cdy7uua7fh8z/7wUHnYBFp1jnbBurqoThpD/c3a31b64884c3adc2251a225a1ddd1dd/Create_API_-_EN.png?fit=max&auto=format&n=c0RQ9V0YAcT0-8l5&q=85&s=e06ac7e43d4a1203c54472701452352a" alt="Dashboard - Créer des API - Intégrations - Google Endpoints" width="692" height="832" data-path="docs/images/cdy7uua7fh8z/7wUHnYBFp1jnbBurqoThpD/c3a31b64884c3adc2251a225a1ddd1dd/Create_API_-_EN.png" />
</Frame>

Prenez en note l’identifiant **Audience de l’API <Tooltip tip="Audience : identifiant unique de l’audience d’un jeton émis. Appelée aud dans un jeton, sa valeur contient l’ID d’une application (ID client) pour un ID Token ou d’une API (identifiant d’API) pour un Jeton d’accès." cta="Voir le glossaire" href="/fr-CA/docs/glossary?term=Audience">Audience</Tooltip>** (`http://google_api` dans la capture d’écran ci-dessus) pour l’utiliser à l’étape suivante.

<div id="update-the-api-configuration">
  ## Mettre à jour la configuration de l’API
</div>

Ensuite, nous allons mettre à jour le fichier de configuration OpenAPI de l’API GCE. Pour l’API d’exemple créée dans le guide de démarrage rapide, ce fichier est `openapi.yaml`.

<div id="add-security-definitions">
  ### Ajouter des définitions de sécurité
</div>

Ouvrez le fichier de configuration et ajoutez une nouvelle section `securityDefinitions`. Dans cette section, ajoutez une nouvelle définition (`auth0_jwt`) avec les champs suivants :

| Champ                | Description                                                                                                                                                                                                    |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `authorizationUrl`   | L’URL d’autorisation. Elle doit être définie sur `"https://{yourDomain}/authorize"`                                                                                                                            |
| `flow`               | Le flux utilisé par le schéma de sécurité OAuth2. Les valeurs valides sont `"implicit"`, `"password"`, `"application"` ou `"accessCode"`.                                                                      |
| `type`               | Le type de schéma de sécurité. Les valeurs valides sont `"basic"`, `"apiKey"` ou `"oauth2"`                                                                                                                    |
| `x-google-issuer`    | L’émetteur des informations d’identification. Il doit être défini sur `"https://{yourDomain}/"`                                                                                                                |
| `x-google-jwks_uri`  | L’URI du jeu de clés publiques servant à valider la signature du [JSON Web Token (JWT)](/fr-CA/docs/glossary?term=JSON+Web+Token+%28JWT%29). Définissez-la sur `"https://\{yourDomain}/.well-known/jwks.json"` |
| `x-google-audiences` | L’identifiant de l’API. Assurez-vous que cette valeur correspond à celle que vous avez définie dans l’Auth0 Dashboard pour l’API.                                                                              |

export const codeExample1 = `securityDefinitions:
  auth0_jwt:
    authorizationUrl: "https://{yourDomain}/authorize"
    flow: "implicit"
    type: "oauth2"
    x-google-issuer: "https://{yourDomain}/"
    x-google-jwks_uri: "https://{yourDomain}/.well-known/jwks.json"
    x-google-audiences: "{yourApiIdentifier}"`;

<AuthCodeBlock children={codeExample1} language="yaml" />

<div id="update-the-endpoint">
  ### Mettre à jour le point de terminaison
</div>

Mettez maintenant à jour le point de terminaison en y ajoutant un champ `security` avec le `securityDefinition` créé à l’étape précédente.

```yaml lines theme={null}
paths:
  "/airportName":
    get:
      description: "Get the airport name for a given IATA code."
      operationId: "airportName"
      parameters:
        -
          name: iataCode
          in: query
          required: true
          type: string
      responses:
        200:
          description: "Success."
          schema:
            type: string
        400:
          description: "The IATA code is invalid or missing."
      security:
       - auth0_jwt: []
```

Dans l’exemple ci-dessus, le champ `security` indique au proxy GCE que notre chemin `/airportName` doit être protégé à l’aide de la définition `auth0-jwt`.

Après avoir mis à jour la configuration OpenAPI, elle devrait ressembler à ceci :

export const codeExample2 = `---
swagger: "2.0"
info:
  title: "Codes d’aéroport"
  description: "Obtenir le nom d’un aéroport à partir de son code IATA à trois lettres."
  version: "1.0.0"
host: "{yourGceProject}.appspot.com"
schemes:
  - "https"
paths:
  "/airportName":
    get:
      description: "Obtenir le nom de l’aéroport correspondant à un code IATA donné."
      operationId: "airportName"
      parameters:
        -
          name: iataCode
          in: query
          required: true
          type: string
      responses:
        200:
          description: "Succès."
          schema:
            type: string
        400:
          description: "Le code IATA est non valide ou manquant."
      security:
       - auth0_jwt: []
securityDefinitions:
  auth0_jwt:
    authorizationUrl: "https://{yourDomain}/authorize"
    flow: "implicit"
    type: "oauth2"
    x-google-issuer: "https://{yourDomain}/"
    x-google-jwks_uri: "https://{yourDomain}/.well-known/jwks.json"
    x-google-audiences: "{yourApiIdentifier}"`;

<AuthCodeBlock children={codeExample2} language="yaml" />

<div id="redeploy-the-api">
  ### Redéployez l’API
</div>

Ensuite, redéployez votre API sur GCE pour appliquer les modifications de configuration. Si vous avez suivi le [guide de démarrage rapide de Cloud Endpoints](https://cloud.google.com/endpoints/docs/quickstart-endpoints), vous pouvez la redéployer en saisissant ce qui suit dans le Cloud Shell de Google':

```bash lines theme={null}
cd endpoints-quickstart/scripts
./deploy_api.sh
```

<div id="test-the-api">
  ## Tester l’API
</div>

Une fois le redéploiement effectué, refaites un appel à l’API sans sécurité.

<AuthCodeGroup>
  ```bash cURL lines theme={null}
  curl --request GET \
    --url 'https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO'
  ```

  ```csharp C# lines theme={null}
  var client = new RestClient("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO");
  var request = new RestRequest(Method.GET);
  IRestResponse response = client.Execute(request);
  ```

  ```go Go lines theme={null}
  package main

  import (
  	"fmt"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO"

  	req, _ := http.NewRequest("GET", url, nil)

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java lines theme={null}
  HttpResponse<String> response = Unirest.get("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")
    .asString();
  ```

  ```javascript Node.JS lines theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'GET',
    url: 'https://%7ByourGceProject%7D.appspot.com/airportName',
    params: {iataCode: 'SFO'}
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP lines theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python lines theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  conn.request("GET", "%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby lines theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Get.new(url)

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

Vous obtiendrez la réponse suivante :

```json lines theme={null}
{
 "code": 16,
 "message": "JWT validation failed: Missing or invalid credentials",
 "details": [
  {
   "@type": "type.googleapis.com/google.rpc.DebugInfo",
   "stackEntries": [],
   "detail": "auth"
  }
 ]
}
```

C’est exactement ce que nous voulons !

Maintenant, allez à la page **Test** de la définition de votre API Google Endpoints dans le [Auth0 Dashboard](https://manage.auth0.com/#/apis), puis copiez le <Tooltip tip="Jeton d’accès : jeton d’autorisation, sous la forme d’une chaîne opaque ou d’un JWT, utilisé pour accéder à une API." cta="Voir le glossaire" href="/fr-CA/docs/glossary?term=Access+Token">Jeton d’accès</Tooltip> sous la réponse :

Effectuez une requête `GET` vers votre API avec un en-tête Authorization de `Bearer {ACCESS_TOKEN}` pour y accéder de façon autorisée :

<AuthCodeGroup>
  ```bash cURL lines theme={null}
  curl --request GET \
    --url 'https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO' \
    --header 'authorization: Bearer {accessToken}'
  ```

  ```csharp C# lines theme={null}
  var client = new RestClient("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO");
  var request = new RestRequest(Method.GET);
  request.AddHeader("authorization", "Bearer {accessToken}");
  IRestResponse response = client.Execute(request);
  ```

  ```go Go lines theme={null}
  package main

  import (
  	"fmt"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO"

  	req, _ := http.NewRequest("GET", url, nil)

  	req.Header.Add("authorization", "Bearer {accessToken}")

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java lines theme={null}
  HttpResponse<String> response = Unirest.get("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")
    .header("authorization", "Bearer {accessToken}")
    .asString();
  ```

  ```javascript Node.JS lines theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'GET',
    url: 'https://%7ByourGceProject%7D.appspot.com/airportName',
    params: {iataCode: 'SFO'},
    headers: {authorization: 'Bearer {accessToken}'}
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP lines theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => [
      "authorization: Bearer {accessToken}"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python lines theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  headers = { 'authorization': "Bearer {accessToken}" }

  conn.request("GET", "%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO", headers=headers)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby lines theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Get.new(url)
  request["authorization"] = 'Bearer {accessToken}'

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

C’est tout !
