Configurer le partage des ressources entre origines multiples (CORS)

Accéder aux concepts

Le partage des ressources entre origines multiples (CORS, Cross Origin Resource Sharing) est un mécanisme permettant les interactions entre des ressources d'origines différentes, ce qui est normalement interdit afin d'empêcher tout comportement malveillant. Cet article explique comment configurer le CORS sur un bucket Cloud Storage.

Configurer le CORS sur un bucket

Pour définir la configuration CORS sur un bucket, spécifiez des informations telles que les méthodes HTTP et les domaines d'origine, qui identifient les types de requêtes qu'il acceptera. Vous pouvez utiliser l'outil de ligne de commande gsutil, l'API XML, l'API JSON ou les bibliothèques clientes pour Cloud Storage pour définir la configuration CORS sur un bucket.

L'exemple suivant montre comment configurer le CORS dans votre bucket. La configuration CORS est définie comme suit :

  • Elle autorise les requêtes provenant de example.appspot.com.
  • Elle autorise les requêtes qui utilisent la méthode HTTP GET.
  • Elle autorise le partage de l'en-tête de réponse Content-Type entre plusieurs origines.
  • Dans le cas des requêtes pré-vérifiées, elle permet au navigateur d'effectuer des requêtes pendant 3 600 secondes (une heure) avant qu'il ne doive répéter la requête de pré-vérification.

gsutil

  1. Créez un fichier JSON contenant les informations suivantes :

    [
        {
          "origin": ["http://example.appspot.com"],
          "responseHeader": ["Content-Type"],
          "method": ["GET"],
          "maxAgeSeconds": 3600
        }
    ]
  2. Exécutez la commande gsutil cors pour configurer le CORS sur un bucket :

    gsutil cors set [JSON_FILE_NAME].json gs://[BUCKET_NAME]

    • [JSON_FILE_NAME] est le chemin d'accès au fichier JSON que vous avez créé à l'étape 1.
    • [BUCKET_NAME] est le nom du bucket. Exemple :my-bucket

Exemples de code

C++

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage C++.

namespace gcs = google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string bucket_name, std::string origin) {
  StatusOr<gcs::BucketMetadata> original =
      client.GetBucketMetadata(bucket_name);

  if (!original) throw std::runtime_error(original.status().message());
  std::vector<gcs::CorsEntry> cors_configuration;
  cors_configuration.emplace_back(
      gcs::CorsEntry{3600, {"GET"}, {origin}, {"Content-Type"}});

  StatusOr<gcs::BucketMetadata> patched_metadata = client.PatchBucket(
      bucket_name,
      gcs::BucketMetadataPatchBuilder().SetCors(cors_configuration),
      gcs::IfMetagenerationMatch(original->metageneration()));

  if (!patched_metadata) {
    throw std::runtime_error(patched_metadata.status().message());
  }

  if (patched_metadata->cors().empty()) {
    std::cout << "Cors configuration is not set for bucket "
              << patched_metadata->name() << "\n";
    return;
  }

  std::cout << "Cors configuration successfully set for bucket "
            << patched_metadata->name() << "\nNew cors configuration: ";
  for (auto const& cors_entry : patched_metadata->cors()) {
    std::cout << "\n  " << cors_entry << "\n";
  }
}

Java

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage Java.

import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.Cors;
import com.google.cloud.storage.HttpMethod;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import com.google.common.collect.ImmutableList;

public class ConfigureBucketCors {
  public static void configureBucketCors(
      String projectId,
      String bucketName,
      String origin,
      String responseHeader,
      Integer maxAgeSeconds) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";

    // The origin for this CORS config to allow requests from
    // String origin = "http://example.appspot.com";

    // The response header to share across origins
    // String responseHeader = "Content-Type";

    // The maximum amount of time the browser can make requests before it must repeat preflighted
    // requests
    // Integer maxAgeSeconds = 3600;

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
    Bucket bucket = storage.get(bucketName);

    // See the HttpMethod documentation for other HTTP methods available:
    // https://cloud.google.com/appengine/docs/standard/java/javadoc/com/google/appengine/api/urlfetch/HTTPMethod
    HttpMethod method = HttpMethod.GET;

    Cors cors =
        Cors.newBuilder()
            .setOrigins(ImmutableList.of(Cors.Origin.of(origin)))
            .setMethods(ImmutableList.of(method))
            .setResponseHeaders(ImmutableList.of(responseHeader))
            .setMaxAgeSeconds(maxAgeSeconds)
            .build();

    bucket.toBuilder().setCors(ImmutableList.of(cors)).build().update();

    System.out.println(
        "Bucket "
            + bucketName
            + " was updated with a CORS config to allow GET requests from "
            + origin
            + " sharing "
            + responseHeader
            + " responses across origins");
  }
}

C#

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage C#.

Actuellement, vous ne pouvez pas configurer le CORS avec la bibliothèque cliente C#.

Go

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage Go.

Pour définir une configuration CORS pour un bucket à l'aide de Go, consultez la documentation de référence sur le type CORS.

Node.js

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage Node.js.

Pour définir une configuration CORS pour un bucket à l'aide de NodeJS, consultez la documentation de référence sur l'objet Bucket.

PHP

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage PHP.

Pour définir une configuration CORS pour un bucket à l'aide de PHP, consultez la documentation de référence sur Google\Cloud\Storage\Bucket.

Python

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage Python.

Pour définir une configuration CORS pour un bucket à l'aide de Python, consultez la documentation de référence sur la propriété cors.

Ruby

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage Ruby.

Pour définir une configuration CORS pour un bucket à l'aide de Ruby, consultez la documentation de référence sur Google::Cloud::Storage.

API REST

API JSON

  1. Obtenez un jeton d'autorisation d'accès sur la page OAuth 2.0 Playground. Configurez Playground pour utiliser vos propres identifiants OAuth.
  2. Créez un fichier JSON contenant les informations suivantes :

    {
    "cors": [
      {
        "origin": [
          "http://example.appspot.com"
        ],
        "method": [
          "GET"
        ],
        "responseHeader": [
          "Content-Type"
        ],
        "maxAgeSeconds": 3600
      }
    ]
    }
  3. Exécutez cURL pour appeler l'API JSON avec une requête de bucket PATCH :

    curl --request PATCH \
    'https://storage.googleapis.com/storage/v1/b/[BUCKET_NAME]' \
    --header 'Authorization: Bearer [OAUTH2_TOKEN]' \
    --header 'Content-Type: application/json' \
    --data-binary @[JSON_FILE_NAME].json

    Où :

    • [BUCKET_NAME] est le nom du bucket. Exemple :my-bucket
    • [OAUTH2_TOKEN] correspond au jeton d'accès que vous avez généré à l'étape 1.
    • [JSON_FILE_NAME] est le chemin d'accès au fichier que vous avez créé à l'étape 2.

API XML

  1. Obtenez un jeton d'autorisation d'accès sur la page OAuth 2.0 Playground. Configurez Playground pour utiliser vos propres identifiants OAuth.
  2. Créez un fichier XML contenant les informations suivantes :

    <?xml version="1.0" encoding="UTF-8"?>
    <CorsConfig>
    <Cors>
      <Origins>
        <Origin>http://example.appspot.com</Origin>
      </Origins>
      <Methods>
        <Method>GET</Method>
      </Methods>
      <ResponseHeaders>
        <ResponseHeader>Content-Type</ResponseHeader>
      </ResponseHeaders>
      <MaxAgeSec>3600</MaxAgeSec>
    </Cors>
    </CorsConfig>
    
  3. Exécutez cURL pour appeler l'API XML avec une requête Set Bucket CORS :

    curl -X PUT --data-binary @[XML_FILE_NAME].xml \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    -H "x-goog-project-id: [PROJECT_ID]" \
    "https://storage.googleapis.com/[BUCKET_NAME]?cors"

    Où :

    • [BUCKET_NAME] est le nom du bucket. Exemple :my-bucket
    • [OAUTH2_TOKEN] correspond au jeton d'accès que vous avez généré à l'étape 1.
    • [PROJECT_ID] est l'ID du projet associé au bucket. Exemple :my-project
    • [XML_FILE_NAME] est le chemin d'accès au fichier que vous avez créé à l'étape 2.

Afficher la configuration CORS d'un bucket

Pour afficher la configuration CORS d'un bucket, procédez comme suit :

gsutil

Exécutez la commande gsutil cors pour obtenir la configuration CORS d'un bucket :

gsutil cors get gs://[BUCKET_NAME]

[BUCKET_NAME] est le nom du bucket. Exemple :my-bucket

Exemples de code

Pour afficher la configuration CORS d'un bucket à l'aide des bibliothèques clientes, suivez les instructions pour afficher les métadonnées d'un bucket et recherchez le champ CORS dans la réponse.

API REST

API JSON

  1. Obtenez un jeton d'autorisation d'accès sur la page OAuth 2.0 Playground. Configurez Playground pour utiliser vos propres identifiants OAuth.
  2. Exécutez cURL pour appeler l'API JSON avec une requête de bucket GET :

    curl -X GET \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    "https://storage.googleapis.com/storage/v1/b/[BUCKET_NAME]?fields=cors"

    Où :

    • [OAUTH2_TOKEN] correspond au nom du jeton d'accès que vous avez généré à l'étape 1.
    • [BUCKET_NAME] correspond au nom du bucket concerné. Exemple : my-bucket.

API XML

  1. Obtenez un jeton d'autorisation d'accès sur la page OAuth 2.0 Playground. Configurez Playground pour utiliser vos propres identifiants OAuth.
  2. Utilisez cURL pour appeler l'API XML avec une requête GET Bucket :

    curl -X GET \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    "https://storage.googleapis.com/[BUCKET_NAME]?cors"

    Où :

    • [OAUTH2_TOKEN] correspond au nom du jeton d'accès que vous avez généré à l'étape 1.
    • [BUCKET_NAME] correspond au nom du bucket concerné. Exemple : my-bucket.

Supprimer le CORS d'un bucket

Pour supprimer la configuration CORS d'un bucket, procédez comme suit :

gsutil

  1. Créez un fichier JSON contenant les informations suivantes :

    []
  2. Exécutez la commande gsutil cors pour configurer le CORS sur un bucket :

    gsutil cors set [JSON_FILE_NAME].json gs://[BUCKET_NAME]

    • [JSON_FILE_NAME] est le chemin d'accès au fichier JSON que vous avez créé à l'étape 1.
    • [BUCKET_NAME] est le nom du bucket. Exemple :my-bucket

API REST

API JSON

  1. Obtenez un jeton d'autorisation d'accès sur la page OAuth 2.0 Playground. Configurez Playground pour utiliser vos propres identifiants OAuth.
  2. Créez un fichier JSON contenant les informations suivantes :

    {
    "cors": []
    }
  3. Exécutez cURL pour appeler l'API JSON avec une requête de bucket PATCH :

    curl --request PATCH \
    'https://storage.googleapis.com/storage/v1/b/[BUCKET_NAME]' \
    --header 'Authorization: Bearer [OAUTH2_TOKEN]' \
    --header 'Content-Type: application/json' \
    --data-binary @[JSON_FILE_NAME].json

    Où :

    • [BUCKET_NAME] est le nom du bucket. Exemple :my-bucket
    • [OAUTH2_TOKEN] correspond au jeton d'accès que vous avez généré à l'étape 1.
    • [JSON_FILE_NAME] est le chemin d'accès au fichier que vous avez créé à l'étape 2.

API XML

  1. Obtenez un jeton d'autorisation d'accès sur la page OAuth 2.0 Playground. Configurez Playground pour utiliser vos propres identifiants OAuth.
  2. Créez un fichier XML contenant les informations suivantes :

    <CorsConfig></CorsConfig>
  3. Exécutez cURL pour appeler l'API XML avec une requête Set Bucket CORS :

    curl -X PUT --data-binary @[XML_FILE_NAME].xml \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    -H "x-goog-project-id: [PROJECT_ID]" \
    "https://storage.googleapis.com/[BUCKET_NAME]?cors"

    Où :

    • [BUCKET_NAME] est le nom du bucket. Exemple :my-bucket
    • [OAUTH2_TOKEN] correspond au jeton d'accès que vous avez généré à l'étape 1.
    • [PROJECT_ID] est l'ID du projet associé au bucket. Exemple :my-project
    • [XML_FILE_NAME] est le chemin d'accès au fichier que vous avez créé à l'étape 2.

Résoudre les problèmes liés aux requêtes CORS

Si vous constatez un comportement inattendu lorsque vous accédez à des buckets Cloud Storage d'une autre origine, procédez comme suit :

  1. Utilisez gsutil cors get sur le bucket cible pour obtenir sa configuration CORS. Si vous disposez de plusieurs entrées de configuration CORS, assurez-vous que les valeurs de la requête sont mappées avec les valeurs d'une seule entrée de configuration CORS tout au long des étapes suivantes.

  2. Vérifiez que vous n'envoyez pas de requête au point de terminaison storage.cloud.google.com, qui n'autorise pas les requêtes CORS. Pour plus d'informations sur les points de terminaison compatibles avec le CORS, consultez la section Compatibilité du CORS avec Cloud Storage.

  3. Examinez une requête et sa réponse à l'aide de l'outil de votre choix. Dans un navigateur Chrome, vous pouvez utiliser les outils de développement standards pour afficher ces informations :

    1. Cliquez sur le menu Chrome Icône du menu Chrome. dans la barre d'outils du navigateur.
    2. Sélectionnez Plus d'outils > Outils de développement.
    3. Cliquez sur l'onglet Réseau.
    4. À partir de votre application ou de votre ligne de commande, envoyez la requête.
    5. Dans le volet affichant l'activité du réseau, localisez la requête.
    6. Dans la colonne Name (Nom), cliquez sur le nom correspondant à la requête.
    7. Cliquez sur l'onglet Headers (En-têtes) pour voir les en-têtes de réponse ou sur l'onglet Response (Réponse) pour voir le contenu de la réponse.

    Si vous ne voyez ni requête ni réponse, il est possible que votre navigateur ait mis en cache une tentative de requête de pré-vérification ayant échoué précédemment. Si vous videz le cache de votre navigateur, cela devrait également vider le cache de pré-vérification. Dans le cas contraire, diminuez la valeur MaxAgeSec dans votre configuration CORS (la valeur par défaut est 1 800 (30 minutes) si elle n'est pas spécifiée), attendez pendant la durée de l'ancienne valeur MaxAgeSec, puis renouvelez la requête. Cela entraîne l'exécution d'une nouvelle requête de pré-vérification, qui récupère la nouvelle configuration CORS et purge les entrées du cache. Une fois que vous avez résolu votre problème, augmentez à nouveau la valeur MaxAgeSec afin de réduire le trafic de pré-vérification dans le bucket.

  4. Assurez-vous que la requête comporte un en-tête Origin et que la valeur de celui-ci correspond à au moins l'une des valeurs Origins figurant dans la configuration CORS du bucket. Notez que le schéma, l'hôte et le port des valeurs doivent correspondre exactement. Voici quelques exemples de correspondances acceptables :

    • http://origin.example.com correspond à http://origin.example.com:80 (car 80 est le port HTTP par défaut), mais ne correspond pas à https://origin.example.com, ni à http://origin.example.com:8080, http://origin.example.com:5151 et http://sub.origin.example.com.

    • https://example.com:443 correspond à https://example.com, mais pas à http://example.com ni à http://example.com:443.

    • http://localhost:8080 ne correspond exactement qu'à http://localhost:8080, pas à http://localhost:5555 ni à http://localhost.example.com:8080.

  5. Assurez-vous que la méthode HTTP de la requête (s'il s'agit d'une requête simple) ou que la méthode spécifiée dans Access-Control-Request-Method (s'il s'agit d'une requête de pré-vérification) correspond à au moins l'une des valeurs Methods figurant dans la configuration CORS du bucket.

  6. S'il s'agit d'une requête de pré-vérification, voyez si elle inclut un ou plusieurs en-têtes Access-Control-Request-Header. Le cas échéant, assurez-vous que chaque valeur Access-Control-Request-Header correspond à une valeur ResponseHeader de la configuration CORS du bucket. Tous les en-têtes nommés dans Access-Control-Request-Header doivent figurer dans la configuration CORS pour que la requête de pré-vérification aboutisse et pour inclure les en-têtes CORS dans la réponse.