Configurer l'authentification pour des applications de production serveur à serveur

Ce guide explique comment configurer l'authentification et l'autorisation pour les applications de production serveur à serveur dans les API Google Cloud. L'authentification fait référence au processus permettant de déterminer l'identité d'un client. L'autorisation fait référence au processus permettant de déterminer les autorisations dont dispose un client authentifié sur une ressource spécifique. En résumé, l'authentification vous identifie et l'autorisation détermine ce que vous pouvez faire. Pour plus d'informations sur les méthodes d'authentification compatibles et sur la façon de les choisir, consultez la page Présentation de l'authentification.

Google utilise des identifiants pour identifier votre application en ce qui concerne les quotas et la facturation. Vos identifiants servent également à autoriser l'accès aux API, ressources et fonctionnalités de Google Cloud.

Fournir des identifiants à votre application

Rechercher automatiquement des identifiants

Pour trouver les identifiants de votre application, les bibliothèques clientes Google Cloud utilisent la stratégie des identifiants par défaut de l'application (ADC). Lorsque votre code utilise une bibliothèque cliente, la stratégie vérifie vos identifiants dans l'ordre suivant :

  1. D'abord, l'ADC vérifie si la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS est définie. Si elle est définie, l'ADC utilise le fichier de compte de service vers lequel la variable renvoie. La section suivante explique comment définir la variable d'environnement.

  2. Si la variable d'environnement n'est pas définie, l'ADC utilise le compte de service par défaut fourni par Compute Engine, Google Kubernetes Engine, Cloud Run, App Engine et Cloud Functions, pour les applications exécutées sur ces services.

  3. Si l'ADC ne peut utiliser aucune des informations d'identification ci-dessus, une erreur se produit.

L'exemple de code suivant illustre cette stratégie. Il n'indique pas explicitement les identifiants de l'application. Toutefois, l'ADC peut rechercher implicitement les identifiants tant que la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS est définie, ou que l'application s'exécute sur Compute Engine, GKE, App Engine ou Cloud Functions.

Vous devez installer la bibliothèque cliente Cloud Storage pour exécuter l'exemple suivant.

C#

public object AuthImplicit(string projectId)
{
    // If you don't specify credentials when constructing the client, the
    // client library will look for credentials in the environment.
    var credential = GoogleCredential.GetApplicationDefault();
    var storage = StorageClient.Create(credential);
    // Make an authenticated API request.
    var buckets = storage.ListBuckets(projectId);
    foreach (var bucket in buckets)
    {
        Console.WriteLine(bucket.Name);
    }
    return null;
}

Go


// implicit uses Application Default Credentials to authenticate.
func implicit() {
	ctx := context.Background()

	// For API packages whose import path is starting with "cloud.google.com/go",
	// such as cloud.google.com/go/storage in this case, if there are no credentials
	// provided, the client library will look for credentials in the environment.
	storageClient, err := storage.NewClient(ctx)
	if err != nil {
		log.Fatal(err)
	}

	it := storageClient.Buckets(ctx, "project-id")
	for {
		bucketAttrs, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(bucketAttrs.Name)
	}

	// For packages whose import path is starting with "google.golang.org/api",
	// such as google.golang.org/api/cloudkms/v1, use NewService to create the client.
	kmsService, err := cloudkms.NewService(ctx)
	if err != nil {
		log.Fatal(err)
	}

	_ = kmsService
}

Java

static void authImplicit() {
  // If you don't specify credentials when constructing the client, the client library will
  // look for credentials via the environment variable GOOGLE_APPLICATION_CREDENTIALS.
  Storage storage = StorageOptions.getDefaultInstance().getService();

  System.out.println("Buckets:");
  Page<Bucket> buckets = storage.list();
  for (Bucket bucket : buckets.iterateAll()) {
    System.out.println(bucket.toString());
  }
}

Node.js

// Imports the Google Cloud client library.
const {Storage} = require('@google-cloud/storage');

// Instantiates a client. If you don't specify credentials when constructing
// the client, the client library will look for credentials in the
// environment.
const storage = new Storage();
// Makes an authenticated API request.
async function listBuckets() {
  try {
    const results = await storage.getBuckets();

    const [buckets] = results;

    console.log('Buckets:');
    buckets.forEach((bucket) => {
      console.log(bucket.name);
    });
  } catch (err) {
    console.error('ERROR:', err);
  }
}
listBuckets();

PHP

// Imports the Cloud Storage client library.
use Google\Cloud\Storage\StorageClient;

function auth_cloud_implicit($projectId)
{
    $config = [
        'projectId' => $projectId,
    ];

    # If you don't specify credentials when constructing the client, the
    # client library will look for credentials in the environment.
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python

def implicit():
    from google.cloud import storage

    # If you don't specify credentials when constructing the client, the
    # client library will look for credentials in the environment.
    storage_client = storage.Client()

    # Make an authenticated API request
    buckets = list(storage_client.list_buckets())
    print(buckets)

Ruby

# project_id = "Your Google Cloud project ID"

require "google/cloud/storage"

# If you don't specify credentials when constructing the client, the client
# library will look for credentials in the environment.
storage = Google::Cloud::Storage.new project: project_id

# Make an authenticated API request
storage.buckets.each do |bucket|
  puts bucket.name
end

Cette stratégie est utile lors des tests et des expérimentations, mais peut vous empêcher de déterminer les identifiants utilisés par votre application. Nous vous recommandons de spécifier explicitement les identifiants que l'application doit utiliser, comme décrit dans la section suivante.

Obtenir et fournir les identifiants du compte de service manuellement

Si vous développez du code localement et que vous déployez votre application sur site ou dans un autre cloud public, vous pouvez créer et obtenir manuellement les identifiants du compte de service.

Créer un compte de service

Les étapes ci-dessous indiquent comment créer un compte de service. Toutefois, au lieu de définir des autorisations au niveau du propriétaire, vous devez restreindre l'accès aux autorisations, comme indiqué dans la section Restreindre l'accès ci-dessous.

Cloud Console

  1. Dans Cloud Console, accédez à la page Créer une clé de compte de service.

    Accéder à la page Créer une clé de compte de service
  2. Dans la liste Compte de service, sélectionnez Nouveau compte de service.
  3. Dans le champ Nom du compte de service, saisissez un nom.
  4. Dans la liste Rôle, sélectionnez Projet > Propriétaire.

    Remarque : Le champ Rôle autorise votre compte de service à accéder aux ressources. Vous pourrez afficher et modifier ce champ ultérieurement à l'aide de Cloud Console. Si vous développez une application de production, spécifiez des autorisations plus précises que Projet > Propriétaire. Pour plus d'informations, consultez la page Attribuer des rôles aux comptes de service.
  5. Cliquez sur Créer. Un fichier JSON contenant votre clé est téléchargé sur votre ordinateur.

Ligne de commande

Vous pouvez exécuter les commandes suivantes à l'aide du SDK Cloud sur votre ordinateur local, ou dans Cloud Shell.

  1. Créez le compte de service. Remplacez [NAME] par le nom que vous souhaitez donner au compte de service.

    gcloud iam service-accounts create [NAME]
  2. Accordez des autorisations au compte de service. Remplacez [PROJECT_ID] par votre ID de projet.

    gcloud projects add-iam-policy-binding [PROJECT_ID] --member "serviceAccount:[NAME]@[PROJECT_ID].iam.gserviceaccount.com" --role "roles/owner"
    Remarque : Le champ Rôle autorise votre compte de service à accéder aux ressources. Vous pourrez afficher et modifier ce champ ultérieurement à l'aide de Cloud Console. Si vous développez une application de production, spécifiez des autorisations plus précises que Projet > Propriétaire. Pour plus d'informations, consultez la page Attribuer des rôles aux comptes de service.
  3. Générez le fichier de clé. Remplacez [FILE_NAME] par le nom du fichier de clé.

    gcloud iam service-accounts keys create [FILE_NAME].json --iam-account [NAME]@[PROJECT_ID].iam.gserviceaccount.com

Fournir les identifiants du compte de service

Après avoir créé un compte de service, vous avez deux choix pour fournir les identifiants à votre application. Vous pouvez soit définir la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS de manière explicite, soit indiquer le chemin d'accès à la clé du compte de service dans le code.

Définir la variable d'environnement

Fournissez des identifiants d'authentification au code de votre application en définissant la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS. Remplacez [PATH] par le chemin du fichier JSON contenant la clé de votre compte de service. Cette variable ne s'applique qu'à la session d'interface système actuelle. Par conséquent, si vous ouvrez une nouvelle session, vous devez la définir à nouveau.

Linux ou macOS

export GOOGLE_APPLICATION_CREDENTIALS="[PATH]"

Exemple :

export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/my-key.json"

Windows

Avec PowerShell :

$env:GOOGLE_APPLICATION_CREDENTIALS="[PATH]"

Exemple :

$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\my-key.json"

Avec l'invite de commande :

set GOOGLE_APPLICATION_CREDENTIALS=[PATH]

Une fois que vous avez terminé les étapes ci-dessus, l'ADC est en mesure de déterminer implicitement vos identifiants, comme décrit dans la section Fournir des identifiants à votre application ci-dessus. Nous recommandons cette approche, car elle nécessite moins de code. En outre, l'utilisation de la variable d'environnement augmente la portabilité de votre code, car vous pouvez exécuter le même code dans plusieurs environnements avec des comptes de service différents.

Indiquer le chemin d'accès à la clé du compte de service dans le code

Vous pouvez choisir de renvoyer explicitement vers votre fichier de compte de service dans le code, comme illustré dans l'exemple de code suivant.

Vous devez installer la bibliothèque cliente Cloud Storage pour exécuter l'exemple suivant.

C#

        // Some APIs, like Storage, accept a credential in their Create()
        // method.
        public object AuthExplicit(string projectId, string jsonPath)
        {
            // Explicitly use service account credentials by specifying
            // the private key file.
            var credential = GoogleCredential.FromFile(jsonPath);
            var storage = StorageClient.Create(credential);
            // Make an authenticated API request.
            var buckets = storage.ListBuckets(projectId);
            foreach (var bucket in buckets)
            {
                Console.WriteLine(bucket.Name);
            }
            return null;
        }
        // Other APIs, like Language, accept a channel in their Create()
        // method.
        public object AuthExplicit(string projectId, string jsonPath)
        {
            LanguageServiceClientBuilder builder = new LanguageServiceClientBuilder
            {
                CredentialsPath = jsonPath
            };

            LanguageServiceClient client = builder.Build();
            AnalyzeSentiment(client);
            return 0;
        }

Go


// explicit reads credentials from the specified path.
func explicit(jsonPath, projectID string) {
	ctx := context.Background()
	client, err := storage.NewClient(ctx, option.WithCredentialsFile(jsonPath))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Buckets:")
	it := client.Buckets(ctx, projectID)
	for {
		battrs, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(battrs.Name)
	}
}

Java

static void authExplicit(String jsonPath) throws IOException {
  // You can specify a credential file by providing a path to GoogleCredentials.
  // Otherwise credentials are read from the GOOGLE_APPLICATION_CREDENTIALS environment variable.
  GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath))
        .createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform"));
  Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

  System.out.println("Buckets:");
  Page<Bucket> buckets = storage.list();
  for (Bucket bucket : buckets.iterateAll()) {
    System.out.println(bucket.toString());
  }
}

Node.js

// Imports the Google Cloud client library.
const {Storage} = require('@google-cloud/storage');

// Instantiates a client. Explicitly use service account credentials by
// specifying the private key file. All clients in google-cloud-node have this
// helper, see https://github.com/GoogleCloudPlatform/google-cloud-node/blob/master/docs/authentication.md
// const projectId = 'project-id'
// const keyFilename = '/path/to/keyfile.json'
const storage = new Storage({projectId, keyFilename});

// Makes an authenticated API request.
async function listBuckets() {
  try {
    const [buckets] = await storage.getBuckets();

    console.log('Buckets:');
    buckets.forEach((bucket) => {
      console.log(bucket.name);
    });
  } catch (err) {
    console.error('ERROR:', err);
  }
}
listBuckets();

PHP

namespace Google\Cloud\Samples\Auth;

// Imports the Cloud Storage client library.
use Google\Cloud\Storage\StorageClient;

function auth_cloud_explicit($projectId, $serviceAccountPath)
{
    # Explicitly use service account credentials by specifying the private key
    # file.
    $config = [
        'keyFilePath' => $serviceAccountPath,
        'projectId' => $projectId,
    ];
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python

def explicit():
    from google.cloud import storage

    # Explicitly use service account credentials by specifying the private key
    # file.
    storage_client = storage.Client.from_service_account_json(
        'service_account.json')

    # Make an authenticated API request
    buckets = list(storage_client.list_buckets())
    print(buckets)

Ruby

# project_id = "Your Google Cloud project ID"
# key_file   = "path/to/service-account.json"
require "google/cloud/storage"

# Explicitly use service account credentials by specifying the private key
# file.
storage = Google::Cloud::Storage.new project: project_id, keyfile: key_file

# Make an authenticated API request
storage.buckets.each do |bucket|
  puts bucket.name
end

Obtenir les identifiants dans Compute Engine, Kubernetes Engine, l'environnement flexible App Engine et Cloud Functions

Si votre application est exécutée sur Compute Engine, GKE, l'environnement flexible App Engine ou Cloud Functions, vous n'avez pas besoin de créer votre propre compte de service. Compute Engine inclut un compte de service par défaut créé automatiquement pour vous. Vous pouvez également attribuer un compte de service différent, par instance, si nécessaire. Lorsque vous créez une instance, celle-ci est automatiquement activée pour s'exécuter en tant que compte de service par défaut et dispose d'un ensemble d'autorisations par défaut. Pour plus d'informations, consultez la section Compte de service Compute Engine par défaut.

Une fois que vous avez configuré un compte de service, l'ADC peut trouver implicitement vos identifiants sans qu'il soit nécessaire de modifier votre code, comme décrit dans la section ci-dessus. Si vous souhaitez utiliser spécifiquement les identifiants Compute Engine, vous pouvez le faire explicitement, comme illustré dans l'exemple de code suivant.

Vous devez installer la bibliothèque cliente Cloud Storage pour exécuter l'exemple suivant.

C#

        // Some APIs, like Storage, accept a credential in their Create()
        // method.
        public object AuthExplicitComputeEngine(string projectId)
        {
            // Explicitly request service account credentials from the compute
            // engine instance.
            GoogleCredential credential =
                GoogleCredential.FromComputeCredential();
            var storage = StorageClient.Create(credential);
            // Make an authenticated API request.
            var buckets = storage.ListBuckets(projectId);
            foreach (var bucket in buckets)
            {
                Console.WriteLine(bucket.Name);
            }
            return null;
        }
        // Other APIs, like Language, accept a channel in their Create()
        // method.
        public object AuthExplicitComputeEngine(string projectId)
        {
            LanguageServiceClientBuilder builder = new LanguageServiceClientBuilder
            {
                ChannelCredentials = GoogleCredential
                .FromComputeCredential()
                .ToChannelCredentials()
            };

            LanguageServiceClient client = builder.Build();
            AnalyzeSentiment(client);
            return 0;
        }

Go


// explicitDefault finds the default credentials.
//
// It is very uncommon to need to explicitly get the default credentials in Go.
// Most of the time, client libraries can use Application Default Credentials
// without having to pass the credentials in directly. See implicit above.
func explicitDefault(projectID string) {
	ctx := context.Background()

	creds, err := google.FindDefaultCredentials(ctx, storage.ScopeReadOnly)
	if err != nil {
		log.Fatal(err)
	}
	client, err := storage.NewClient(ctx, option.WithCredentials(creds))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Buckets:")
	it := client.Buckets(ctx, projectID)
	for {
		battrs, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(battrs.Name)
	}
}

Java

static void authCompute() {
  // Explicitly request service account credentials from the compute engine instance.
  GoogleCredentials credentials = ComputeEngineCredentials.create();
  Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

  System.out.println("Buckets:");
  Page<Bucket> buckets = storage.list();
  for (Bucket bucket : buckets.iterateAll()) {
    System.out.println(bucket.toString());
  }
}

Node.js

'use strict';

const {auth, Compute} = require('google-auth-library');

/**
 * This example directly instantiates a Compute client to acquire credentials.
 * Generally, you wouldn't directly create this class, rather call the
 * `auth.getClient()` method to automatically obtain credentials.
 */
async function main() {
  const client = new Compute({
    // Specifying the serviceAccountEmail is optional. It will use the default
    // service account if one is not defined.
    serviceAccountEmail: 'some-service-account@example.com',
  });
  const projectId = await auth.getProjectId();
  const url = `https://dns.googleapis.com/dns/v1/projects/${projectId}`;
  const res = await client.request({url});
  console.log(res.data);
}

main().catch(console.error);

PHP

namespace Google\Cloud\Samples\Auth;

// Imports GCECredentials and the Cloud Storage client library.
use Google\Auth\Credentials\GCECredentials;
use Google\Cloud\Storage\StorageClient;

function auth_cloud_explicit_compute_engine($projectId)
{
    $gceCredentials = new GCECredentials();
    $config = [
        'projectId' => $projectId,
        'credentialsFetcher' => $gceCredentials,
    ];
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python

def explicit_compute_engine(project):
    from google.auth import compute_engine
    from google.cloud import storage

    # Explicitly use Compute Engine credentials. These credentials are
    # available on Compute Engine, App Engine Flexible, and Container Engine.
    credentials = compute_engine.Credentials()

    # Create the client using the credentials and specifying a project ID.
    storage_client = storage.Client(credentials=credentials, project=project)

    # Make an authenticated API request
    buckets = list(storage_client.list_buckets())
    print(buckets)

Ruby

require "googleauth"
require "google/cloud/env"
require "google/cloud/storage"

# Explicitly use Compute Engine credentials and a project ID to create a new
# Cloud Storage client. These credentials are available on Compute Engine,
# App Engine Flexible, and Container Engine.
storage = Google::Cloud::Storage.new project: Google::Cloud.env.project_id,
                                     keyfile: Google::Auth::GCECredentials.new

# Make an authenticated API request
storage.buckets.each do |bucket|
  puts bucket.name
end

Obtenir des identifiants sur l'environnement standard App Engine

Si votre application est exécutée sur l'environnement standard App Engine, vous pouvez utiliser l'API App Engine App Identity pour obtenir des identifiants.

Une fois que vous avez configuré un compte de service, l'ADC peut trouver implicitement vos identifiants sans qu'il soit nécessaire de modifier votre code, comme décrit dans la section ci-dessus. Si vous souhaitez utiliser spécifiquement les identifiants d'App Engine, vous pouvez le faire de manière explicite, comme illustré dans l'exemple de code suivant.

Vous devez installer la bibliothèque cliente Cloud Storage pour exécuter l'exemple suivant.

PHP

namespace Google\Cloud\Samples\Auth;

// Imports AppIdentityCredentials and the Cloud Storage client library.
use Google\Auth\Credentials\AppIdentityCredentials;
use Google\Cloud\Storage\StorageClient;

function auth_cloud_explicit_app_engine($projectId)
{
    # Learn more about scopes at https://cloud.google.com/storage/docs/authentication#oauth-scopes
    $scope = 'https://www.googleapis.com/auth/devstorage.read_only';
    $gaeCredentials = new AppIdentityCredentials($scope);
    $config = [
        'projectId' => $projectId,
        'credentialsFetcher' => $gaeCredentials,
    ];
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Go


// explicitDefault finds the default credentials.
//
// It is very uncommon to need to explicitly get the default credentials in Go.
// Most of the time, client libraries can use Application Default Credentials
// without having to pass the credentials in directly. See implicit above.
func explicitDefault(projectID string) {
	ctx := context.Background()

	creds, err := google.FindDefaultCredentials(ctx, storage.ScopeReadOnly)
	if err != nil {
		log.Fatal(err)
	}
	client, err := storage.NewClient(ctx, option.WithCredentials(creds))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Buckets:")
	it := client.Buckets(ctx, projectID)
	for {
		battrs, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(battrs.Name)
	}
}

Java

static void authAppEngineStandard() throws IOException {
  // Explicitly request service account credentials from the app engine standard instance.
  GoogleCredentials credentials = AppEngineCredentials.getApplicationDefault();
  Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

  System.out.println("Buckets:");
  Page<Bucket> buckets = storage.list();
  for (Bucket bucket : buckets.iterateAll()) {
    System.out.println(bucket.toString());
  }
}

Python

def explicit_app_engine(project):
    from google.auth import app_engine
    import googleapiclient.discovery

    # Explicitly use App Engine credentials. These credentials are
    # only available when running on App Engine Standard.
    credentials = app_engine.Credentials()

    # Explicitly pass the credentials to the client library.
    storage_client = googleapiclient.discovery.build(
        'storage', 'v1', credentials=credentials)

    # Make an authenticated API request
    buckets = storage_client.buckets().list(project=project).execute()
    print(buckets)

Restreindre l'accès

Accordez uniquement à votre application les autorisations dont elle a besoin pour interagir avec les API, fonctionnalités ou ressources Google Cloud applicables. Google Cloud utilise Cloud Identity and Access Management (Cloud IAM) pour le contrôle des accès. Lorsque vous créez un compte de service, vous pouvez choisir un rôle IAM pour limiter l'accès. La procédure détaillée sur la page Premiers pas avec l'authentification vous indique de choisir le rôle Owner lorsque vous créez un compte de service, mais vous pouvez modifier ce paramètre à tout moment. Pour plus d'informations, consultez la section Attribuer des rôles aux comptes de service.

Bonnes pratiques de gestion des identifiants

Les identifiants permettent d'accéder aux données sensibles. Les pratiques suivantes aident à protéger l'accès à ces ressources.

  • N'intégrez pas les informations secrètes liées à l'authentification dans le code source, tels que les clés API, les jetons OAuth et les identifiants du compte de service. Vous pouvez utiliser une variable d'environnement renvoyant vers des identifiants en dehors du code source de l'application, comme Cloud Key Management Service.

  • Utilisez différents identifiants dans différents contextes, tels que les environnements de test et de production.

  • Ne transférez vos identifiants que via HTTPS pour empêcher un tiers de les intercepter. Ne les transférez jamais en texte clair ou dans l'URL.

  • N'intégrez jamais des identifiants de longue durée dans votre application côté client. Par exemple, n'intégrez pas les identifiants de compte de service dans une application mobile. Les applications côté client peuvent être analysées et les identifiants pourraient facilement être découverts et utilisés par un tiers.

  • Révoquez un jeton si vous n'en avez plus besoin.

Dépanner les erreurs d'API

Pour en savoir plus sur le dépannage des requêtes d'API ayant échoué, consultez la section Erreurs.

Étapes suivantes