Como configurar o compartilhamento de recursos entre origens (CORS, na sigla em inglês)

Acessar conceitos

O Compartilhamento de recursos de origem cruzada (CORS, na sigla em inglês) permite interações entre recursos de diferentes origens, o que normalmente é proibido para evitar comportamentos maliciosos. Neste tópico, ensinamos como configurar o CORS em um bucket do Cloud Storage.

Como configurar o CORS em um bucket

Para configurar o CORS em um bucket, especifique as informações que identificam os tipos de solicitações a serem aceitas, como métodos HTTP e domínios de origem. Para fazer isso, use a ferramenta de linha de comando gsutil, a API XML, a API JSON ou as bibliotecas de cliente do Cloud Storage.

O exemplo a seguir mostra como configurar o CORS no seu intervalo:

gsutil

  1. Crie um arquivo JSON que contenha o seguinte:

    [
        {
          "origin": ["ORIGIN"],
          "method": ["METHOD"],
          "responseHeader": ["HEADER"],
          "maxAgeSeconds": MAX-AGE
        }
    ]

    Em que:

    • ORIGIN é uma origem com permissão para compartilhamento de recursos entre origens com esse bucket. Por exemplo, https://example.appspot.com.
    • METHOD é um método HTTP com permissão para compartilhamento de recursos entre origens com esse bucket. Por exemplo, GET ou PUT.
    • HEADER é um cabeçalho com permissão para compartilhamento de recursos entre origens com esse bucket. Por exemplo, Content-Type.
    • MAX-AGE é o número de segundos que o navegador tem permissão para fazer solicitações antes de repetir a solicitação de simulação. Por exemplo, 3600.

    Para mais informações, consulte Elementos de uma configuração do CORS.

  2. Use o comando gsutil cors para configurar o CORS em um bucket:

    gsutil cors set JSON_FILE_NAME.json gs://BUCKET_NAME

    Onde

    • JSON_FILE_NAME é o caminho para o arquivo JSON que você criou na Etapa 1.
    • BUCKET_NAME é o nome do bucket. Por exemplo, my-bucket.

Amostras de código

C++

Para mais informações, consulte a documentação de referência da API Cloud Storage para C++.

namespace gcs = google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string const& bucket_name,
   std::string const& 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";
  }
}

Go

Para mais informações, consulte a documentação de referência da API Cloud Storage para Go.

import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/storage"
)

// setBucketCORSConfiguration sets a CORS configuration on a bucket.
func setBucketCORSConfiguration(w io.Writer, bucketName string, maxAge time.Duration, methods, origins, responseHeaders []string) error {
	// bucketName := "bucket-name"
	// maxAge := time.Hour
	// methods := []string{"GET"}
	// origins := []string{"some-origin.com"}
	// responseHeaders := []string{"Content-Type"}
	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("storage.NewClient: %v", err)
	}
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, time.Second*10)
	defer cancel()

	bucket := client.Bucket(bucketName)
	bucketAttrsToUpdate := storage.BucketAttrsToUpdate{
		CORS: []storage.CORS{
			{
				MaxAge:          maxAge,
				Methods:         methods,
				Origins:         origins,
				ResponseHeaders: responseHeaders,
			}},
	}
	if _, err := bucket.Update(ctx, bucketAttrsToUpdate); err != nil {
		return fmt.Errorf("Bucket(%q).Update: %v", bucketName, err)
	}
	fmt.Fprintf(w, "Bucket %v was updated with a CORS config to allow %v requests from %v sharing %v responses across origins\n", bucketName, methods, origins, responseHeaders)
	return nil
}

Java

Para mais informações, consulte a documentação de referência da API Cloud Storage para 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");
  }
}

Node.js

Para mais informações, consulte a documentação de referência da API Cloud Storage para Node.js.

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

// Creates a client
const storage = new Storage();

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

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

// The response header to share across origins
// const responseHeader = 'Content-Type';

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

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

async function configureBucketCors() {
  await storage.bucket(bucketName).setCorsConfiguration([
    {
      maxAgeSeconds,
      method: [method],
      origin: [origin],
      responseHeader: [responseHeader],
    },
  ]);

  console.log(`Bucket ${bucketName} was updated with a CORS config
      to allow ${method} requests from ${origin} sharing
      ${responseHeader} responses across origins`);
}

configureBucketCors().catch(console.error);

Python

Para mais informações, consulte a documentação de referência da API Cloud Storage para Python.

from google.cloud import storage

def cors_configuration(bucket_name):
    """Set a bucket's CORS policies configuration."""
    # bucket_name = "your-bucket-name"

    storage_client = storage.Client()
    bucket = storage_client.get_bucket(bucket_name)
    bucket.cors = [
        {
            "origin": ["*"],
            "responseHeader": [
                "Content-Type",
                "x-goog-resumable"],
            "method": ['PUT', 'POST'],
            "maxAgeSeconds": 3600
        }
    ]
    bucket.patch()

    print("Set CORS policies for bucket {} is {}".format(bucket.name, bucket.cors))
    return bucket

Ruby

Para mais informações, consulte a documentação de referência da API Cloud Storage para Ruby.

def cors_configuration bucket_name:
  # The ID of your GCS bucket
  # bucket_name = "your-unique-bucket-name"

  require "google/cloud/storage"

  storage = Google::Cloud::Storage.new
  bucket = storage.bucket bucket_name

  bucket.cors do |c|
    c.add_rule ["*"],
               ["PUT", "POST"],
               headers: [
                 "Content-Type",
                 "x-goog-resumable"
               ],
               max_age: 3600
  end

  puts "Set CORS policies for bucket #{bucket_name}"
end

C#

Para mais informações, consulte a documentação de referência da API Cloud Storage para C#.

No momento, não é possível configurar o CORS com a biblioteca de cliente C#.

PHP

Para mais informações, consulte a documentação de referência da API Cloud Storage para PHP.

Para definir uma configuração de CORS para um bucket usando PHP, consulte a documentação de referência do Google\Cloud\Storage\Bucket.

APIs REST

API JSON

  1. Consiga um token de acesso de autorização do OAuth 2.0 Playground (em inglês). Configure o Playground para usar suas credenciais do OAuth.
  2. Crie um arquivo JSON que contenha o seguinte:

    {
     "cors": [
       {
         "origin": [
           "ORIGIN"
         ],
         "method": [
           "METHOD"
         ],
         "responseHeader": [
           "HEADER"
         ],
         "maxAgeSeconds": MAX-AGE
       }
     ]
    }

    Em que:

    • ORIGIN é uma origem com permissão para compartilhamento de recursos entre origens com esse bucket. Por exemplo, https://example.appspot.com.
    • METHOD é um método HTTP com permissão para compartilhamento de recursos entre origens com esse bucket. Por exemplo, GET ou PUT.
    • HEADER é um cabeçalho com permissão para compartilhamento de recursos entre origens com esse bucket. Por exemplo, Content-Type.
    • MAX-AGE é o número de segundos que o navegador tem permissão para fazer solicitações antes de repetir a solicitação de simulação. Por exemplo, 3600.

    Para mais informações, consulte Elementos de uma configuração do CORS.

  3. Use cURL para chamar a API JSON com uma solicitação PATCH bucket:

    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

    Em que:

    • BUCKET_NAME é o nome do bucket. Por exemplo, my-bucket.
    • OAUTH2_TOKEN é o token de acesso gerado na etapa 1;
    • JSON_FILE_NAME é o caminho para o arquivo criado na Etapa 2.

API XML

  1. Consiga um token de acesso de autorização do OAuth 2.0 Playground (em inglês). Configure o Playground para usar suas credenciais do OAuth.
  2. Crie um arquivo XML que contenha o seguinte:

    <?xml version="1.0" encoding="UTF-8"?>
    <CorsConfig>
     <Cors>
       <Origins>
         <Origin>ORIGIN</Origin>
       </Origins>
       <Methods>
         <Method>METHOD</Method>
       </Methods>
       <ResponseHeaders>
         <ResponseHeader>HEADER</ResponseHeader>
       </ResponseHeaders>
       <MaxAgeSec>MAX-AGE</MaxAgeSec>
     </Cors>
    </CorsConfig>
    

    Em que:

    • ORIGIN é uma origem com permissão para compartilhamento de recursos entre origens com esse bucket. Por exemplo, https://example.appspot.com.
    • METHOD é um método HTTP com permissão para compartilhamento de recursos entre origens com esse bucket. Por exemplo, GET ou PUT.
    • HEADER é um cabeçalho com permissão para compartilhamento de recursos entre origens com esse bucket. Por exemplo, Content-Type.
    • MAX-AGE é o número de segundos que o navegador tem permissão para fazer solicitações antes de repetir a solicitação de simulação. Por exemplo, 3600.

    Para mais informações, consulte Elementos de uma configuração do CORS.

  3. Use cURL (em inglês) para chamar a API XML com uma solicitação 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"

    Em que:

    • BUCKET_NAME é o nome do bucket. Por exemplo, my-bucket.
    • OAUTH2_TOKEN é o token de acesso gerado na etapa 1;
    • PROJECT_ID é o ID do projeto associado ao bucket. Por exemplo, my-project.
    • XML_FILE_NAME é o caminho para o arquivo criado na Etapa 2.

Como visualizar a configuração do CORS para um bucket

Para ver a configuração do CORS para um bucket:

gsutil

Use o comando gsutil cors para obter a configuração do CORS de um bucket:

gsutil cors get gs://BUCKET_NAME

Em que BUCKET_NAME é o nome do bucket. Por exemplo, my-bucket.

Amostras de código

Para ver a configuração do CORS para um bucket usando as bibliotecas de cliente, siga as instruções para exibir os metadados de um bucket e procure o campo CORS na resposta.

C++

Para mais informações, consulte a documentação de referência da API Cloud Storage para C++.

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

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

  std::cout << "The metadata for bucket " << bucket_metadata->name() << " is "
            << *bucket_metadata << "\n";
}

C#

Para mais informações, consulte a documentação de referência da API Cloud Storage para C#.


using Google.Apis.Storage.v1.Data;
using Google.Cloud.Storage.V1;
using System;

public class GetBucketMetadataSample
{
    public Bucket GetBucketMetadata(string bucketName = "your-unique-bucket-name")
    {
        var storage = StorageClient.Create();
        var bucket = storage.GetBucket(bucketName, new GetBucketOptions { Projection = Projection.Full });
        Console.WriteLine($"Bucket:\t{bucket.Name}");
        Console.WriteLine($"Acl:\t{bucket.Acl}");
        Console.WriteLine($"Billing:\t{bucket.Billing}");
        Console.WriteLine($"Cors:\t{bucket.Cors}");
        Console.WriteLine($"DefaultEventBasedHold:\t{bucket.DefaultEventBasedHold}");
        Console.WriteLine($"DefaultObjectAcl:\t{bucket.DefaultObjectAcl}");
        Console.WriteLine($"Encryption:\t{bucket.Encryption}");
        if (bucket.Encryption != null)
        {
            Console.WriteLine($"KmsKeyName:\t{bucket.Encryption.DefaultKmsKeyName}");
        }
        Console.WriteLine($"Id:\t{bucket.Id}");
        Console.WriteLine($"Kind:\t{bucket.Kind}");
        Console.WriteLine($"Lifecycle:\t{bucket.Lifecycle}");
        Console.WriteLine($"Location:\t{bucket.Location}");
        Console.WriteLine($"LocationType:\t{bucket.LocationType}");
        Console.WriteLine($"Logging:\t{bucket.Logging}");
        Console.WriteLine($"Metageneration:\t{bucket.Metageneration}");
        Console.WriteLine($"Owner:\t{bucket.Owner}");
        Console.WriteLine($"ProjectNumber:\t{bucket.ProjectNumber}");
        Console.WriteLine($"RetentionPolicy:\t{bucket.RetentionPolicy}");
        Console.WriteLine($"SelfLink:\t{bucket.SelfLink}");
        Console.WriteLine($"StorageClass:\t{bucket.StorageClass}");
        Console.WriteLine($"TimeCreated:\t{bucket.TimeCreated}");
        Console.WriteLine($"Updated:\t{bucket.Updated}");
        Console.WriteLine($"Versioning:\t{bucket.Versioning}");
        Console.WriteLine($"Website:\t{bucket.Website}");
        if (bucket.Labels != null)
        {
            Console.WriteLine("Labels:");
            foreach (var label in bucket.Labels)
            {
                Console.WriteLine($"{label.Key}:\t{label.Value}");
            }
        }
        return bucket;
    }
}

Go

Para mais informações, consulte a documentação de referência da API Cloud Storage para Go.

import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/storage"
)

// getBucketMetadata gets the bucket metadata.
func getBucketMetadata(w io.Writer, bucketName string) (*storage.BucketAttrs, error) {
	// bucketName := "bucket-name"
	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("storage.NewClient: %v", err)
	}
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, time.Second*10)
	defer cancel()
	attrs, err := client.Bucket(bucketName).Attrs(ctx)
	if err != nil {
		return nil, fmt.Errorf("Bucket(%q).Attrs: %v", bucketName, err)
	}
	fmt.Fprintf(w, "BucketName: %v\n", attrs.Name)
	fmt.Fprintf(w, "Location: %v\n", attrs.Location)
	fmt.Fprintf(w, "LocationType: %v\n", attrs.LocationType)
	fmt.Fprintf(w, "StorageClass: %v\n", attrs.StorageClass)
	fmt.Fprintf(w, "TimeCreated: %v\n", attrs.Created)
	fmt.Fprintf(w, "Metageneration: %v\n", attrs.MetaGeneration)
	fmt.Fprintf(w, "PredefinedACL: %v\n", attrs.PredefinedACL)
	if attrs.Encryption != nil {
		fmt.Fprintf(w, "DefaultKmsKeyName: %v\n", attrs.Encryption.DefaultKMSKeyName)
	}
	if attrs.Website != nil {
		fmt.Fprintf(w, "IndexPage: %v\n", attrs.Website.MainPageSuffix)
		fmt.Fprintf(w, "NotFoundPage: %v\n", attrs.Website.NotFoundPage)
	}
	fmt.Fprintf(w, "DefaultEventBasedHold: %v\n", attrs.DefaultEventBasedHold)
	if attrs.RetentionPolicy != nil {
		fmt.Fprintf(w, "RetentionEffectiveTime: %v\n", attrs.RetentionPolicy.EffectiveTime)
		fmt.Fprintf(w, "RetentionPeriod: %v\n", attrs.RetentionPolicy.RetentionPeriod)
		fmt.Fprintf(w, "RetentionPolicyIsLocked: %v\n", attrs.RetentionPolicy.IsLocked)
	}
	fmt.Fprintf(w, "RequesterPays: %v\n", attrs.RequesterPays)
	fmt.Fprintf(w, "VersioningEnabled: %v\n", attrs.VersioningEnabled)
	if attrs.Logging != nil {
		fmt.Fprintf(w, "LogBucket: %v\n", attrs.Logging.LogBucket)
		fmt.Fprintf(w, "LogObjectPrefix: %v\n", attrs.Logging.LogObjectPrefix)
	}
	if attrs.CORS != nil {
		fmt.Fprintln(w, "CORS:")
		for _, v := range attrs.CORS {
			fmt.Fprintf(w, "\tMaxAge: %v\n", v.MaxAge)
			fmt.Fprintf(w, "\tMethods: %v\n", v.Methods)
			fmt.Fprintf(w, "\tOrigins: %v\n", v.Origins)
			fmt.Fprintf(w, "\tResponseHeaders: %v\n", v.ResponseHeaders)
		}
	}
	if attrs.Labels != nil {
		fmt.Fprintf(w, "\n\n\nLabels:")
		for key, value := range attrs.Labels {
			fmt.Fprintf(w, "\t%v = %v\n", key, value)
		}
	}
	return attrs, nil
}

Java

Para mais informações, consulte a documentação de referência da API Cloud Storage para Java.

import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.BucketInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.util.Map;

public class GetBucketMetadata {
  public static void getBucketMetadata(String projectId, String bucketName) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

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

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();

    // Select all fields. Fields can be selected individually e.g. Storage.BucketField.NAME
    Bucket bucket =
        storage.get(bucketName, Storage.BucketGetOption.fields(Storage.BucketField.values()));

    // Print bucket metadata
    System.out.println("BucketName: " + bucket.getName());
    System.out.println("DefaultEventBasedHold: " + bucket.getDefaultEventBasedHold());
    System.out.println("DefaultKmsKeyName: " + bucket.getDefaultKmsKeyName());
    System.out.println("Id: " + bucket.getGeneratedId());
    System.out.println("IndexPage: " + bucket.getIndexPage());
    System.out.println("Location: " + bucket.getLocation());
    System.out.println("LocationType: " + bucket.getLocationType());
    System.out.println("Metageneration: " + bucket.getMetageneration());
    System.out.println("NotFoundPage: " + bucket.getNotFoundPage());
    System.out.println("RetentionEffectiveTime: " + bucket.getRetentionEffectiveTime());
    System.out.println("RetentionPeriod: " + bucket.getRetentionPeriod());
    System.out.println("RetentionPolicyIsLocked: " + bucket.retentionPolicyIsLocked());
    System.out.println("RequesterPays: " + bucket.requesterPays());
    System.out.println("SelfLink: " + bucket.getSelfLink());
    System.out.println("StorageClass: " + bucket.getStorageClass().name());
    System.out.println("TimeCreated: " + bucket.getCreateTime());
    System.out.println("VersioningEnabled: " + bucket.versioningEnabled());
    if (bucket.getLabels() != null) {
      System.out.println("\n\n\nLabels:");
      for (Map.Entry<String, String> label : bucket.getLabels().entrySet()) {
        System.out.println(label.getKey() + "=" + label.getValue());
      }
    }
    if (bucket.getLifecycleRules() != null) {
      System.out.println("\n\n\nLifecycle Rules:");
      for (BucketInfo.LifecycleRule rule : bucket.getLifecycleRules()) {
        System.out.println(rule);
      }
    }
  }
}

Node.js

Para mais informações, consulte a documentação de referência da API Cloud Storage para Node.js.

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

// Creates a client
const storage = new Storage();

async function getBucketMetadata() {
  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // The ID of your GCS bucket
  // const bucketName = 'your-unique-bucket-name';

  // Get Bucket Metadata
  const [metadata] = await storage.bucket(bucketName).getMetadata();

  for (const [key, value] of Object.entries(metadata)) {
    console.log(`${key}: ${value}`);
  }
}

PHP

Para mais informações, consulte a documentação de referência da API Cloud Storage para PHP.

use Google\Cloud\Storage\StorageClient;

/**
 * Get bucket metadata.
 *
 * @param string $bucketName the name of your Cloud Storage bucket.
 *
 * @return void
 */
function get_bucket_metadata($bucketName)
{
    $storage = new StorageClient();
    $bucket = $storage->bucket($bucketName);
    $info = $bucket->info();

    printf("Bucket Metadata: %s" . PHP_EOL, print_r($info));
}

Python

Para mais informações, consulte a documentação de referência da API Cloud Storage para Python.


from google.cloud import storage

def bucket_metadata(bucket_name):
    """Prints out a bucket's metadata."""
    # bucket_name = 'your-bucket-name'

    storage_client = storage.Client()
    bucket = storage_client.get_bucket(bucket_name)

    print("ID: {}".format(bucket.id))
    print("Name: {}".format(bucket.name))
    print("Storage Class: {}".format(bucket.storage_class))
    print("Location: {}".format(bucket.location))
    print("Location Type: {}".format(bucket.location_type))
    print("Cors: {}".format(bucket.cors))
    print(
        "Default Event Based Hold: {}".format(bucket.default_event_based_hold)
    )
    print("Default KMS Key Name: {}".format(bucket.default_kms_key_name))
    print("Metageneration: {}".format(bucket.metageneration))
    print(
        "Retention Effective Time: {}".format(
            bucket.retention_policy_effective_time
        )
    )
    print("Retention Period: {}".format(bucket.retention_period))
    print("Retention Policy Locked: {}".format(bucket.retention_policy_locked))
    print("Requester Pays: {}".format(bucket.requester_pays))
    print("Self Link: {}".format(bucket.self_link))
    print("Time Created: {}".format(bucket.time_created))
    print("Versioning Enabled: {}".format(bucket.versioning_enabled))
    print("Labels:")
    print(bucket.labels)

Ruby

Para mais informações, consulte a documentação de referência da API Cloud Storage para Ruby.

def get_bucket_metadata bucket_name:
  # The ID of your GCS bucket
  # bucket_name = "your-unique-bucket-name"

  require "google/cloud/storage"

  storage = Google::Cloud::Storage.new
  bucket  = storage.bucket bucket_name

  puts "ID:                       #{bucket.id}"
  puts "Name:                     #{bucket.name}"
  puts "Storage Class:            #{bucket.storage_class}"
  puts "Location:                 #{bucket.location}"
  puts "Location Type:            #{bucket.location_type}"
  puts "Cors:                     #{bucket.cors}"
  puts "Default Event Based Hold: #{bucket.default_event_based_hold?}"
  puts "Default KMS Key Name:     #{bucket.default_kms_key}"
  puts "Logging Bucket:           #{bucket.logging_bucket}"
  puts "Logging Prefix:           #{bucket.logging_prefix}"
  puts "Metageneration:           #{bucket.metageneration}"
  puts "Retention Effective Time: #{bucket.retention_effective_at}"
  puts "Retention Period:         #{bucket.retention_period}"
  puts "Retention Policy Locked:  #{bucket.retention_policy_locked?}"
  puts "Requester Pays:           #{bucket.requester_pays}"
  puts "Self Link:                #{bucket.api_url}"
  puts "Time Created:             #{bucket.created_at}"
  puts "Versioning Enabled:       #{bucket.versioning?}"
  puts "Index Page:               #{bucket.website_main}"
  puts "Not Found Page:           #{bucket.website_404}"
  puts "Labels:"
  bucket.labels.each do |key, value|
    puts " - #{key} = #{value}"
  end
  puts "Lifecycle Rules:"
  bucket.lifecycle.each do |rule|
    puts "#{rule.action} - #{rule.storage_class} - #{rule.age} - #{rule.matches_storage_class}"
  end
end

APIs REST

API JSON

  1. Consiga um token de acesso de autorização do OAuth 2.0 Playground (em inglês). Configure o Playground para usar suas credenciais do OAuth.
  2. Use cURL (em inglês) para chamar a API JSON com uma solicitação de bucket GET:

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

    Em que:

    • OAUTH2_TOKEN é o nome do token de acesso que você gerou na etapa 1.
    • BUCKET_NAME é o nome do bucket pertinente. Por exemplo, my-bucket.

API XML

  1. Consiga um token de acesso de autorização do OAuth 2.0 Playground (em inglês). Configure o Playground para usar suas credenciais do OAuth.
  2. Use cURL (em inglês) para chamar a API XML com uma solicitação bucket GET:

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

    Em que:

    • OAUTH2_TOKEN é o nome do token de acesso que você gerou na etapa 1.
    • BUCKET_NAME é o nome do bucket pertinente. Por exemplo, my-bucket.

Como remover o CORS de um bucket

Para remover a configuração do CORS de um bucket:

gsutil

  1. Crie um arquivo JSON que contenha o seguinte:

    []
  2. Use o comando gsutil cors para configurar o CORS em um bucket:

    gsutil cors set JSON_FILE_NAME.json gs://BUCKET_NAME

    Onde

    • JSON_FILE_NAME é o caminho para o arquivo JSON que você criou na Etapa 1.
    • BUCKET_NAME é o nome do bucket. Por exemplo, my-bucket.

Amostras de código

C++

Para mais informações, consulte a documentação de referência da API Cloud Storage para C++.

namespace gcs = google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string const& bucket_name) {
  StatusOr<gcs::BucketMetadata> original =
      client.GetBucketMetadata(bucket_name);
  if (!original) throw std::runtime_error(original.status().message());

  StatusOr<gcs::BucketMetadata> patched = client.PatchBucket(
      bucket_name, gcs::BucketMetadataPatchBuilder().ResetCors(),
      gcs::IfMetagenerationMatch(original->metageneration()));
  if (!patched) throw std::runtime_error(patched.status().message());

  std::cout << "Cors configuration successfully removed for bucket "
            << patched->name() << "\n";
}

Go

Para mais informações, consulte a documentação de referência da API Cloud Storage para Go.

import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/storage"
)

// removeBucketCORSConfiguration removes the CORS configuration from a bucket.
func removeBucketCORSConfiguration(w io.Writer, bucketName string) error {
	// bucketName := "bucket-name"
	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("storage.NewClient: %v", err)
	}
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, time.Second*10)
	defer cancel()

	bucket := client.Bucket(bucketName)
	bucketAttrsToUpdate := storage.BucketAttrsToUpdate{
		CORS: []storage.CORS{},
	}
	if _, err := bucket.Update(ctx, bucketAttrsToUpdate); err != nil {
		return fmt.Errorf("Bucket(%q).Update: %v", bucketName, err)
	}
	fmt.Fprintf(w, "Removed CORS configuration from a bucket %v\n", bucketName)
	return nil
}

Java

Para mais informações, consulte a documentação de referência da API Cloud Storage para Java.

import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.Cors;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.util.ArrayList;
import java.util.List;

public class RemoveBucketCors {
  public static void removeBucketCors(String projectId, String bucketName) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

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

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
    Bucket bucket =
        storage.get(bucketName, Storage.BucketGetOption.fields(Storage.BucketField.CORS));

    // getCors() returns the List and copying over to an ArrayList so it's mutable.
    List<Cors> cors = new ArrayList<>(bucket.getCors());

    // Clear bucket CORS configuration.
    cors.clear();

    // Update bucket to remove CORS.
    bucket.toBuilder().setCors(cors).build().update();
    System.out.println("Removed CORS configuration from bucket " + bucketName);
  }
}

Node.js

Para mais informações, consulte a documentação de referência da API Cloud Storage para Node.js.

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

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

// Creates a client
const storage = new Storage();

async function removeBucketCors() {
  await storage.bucket(bucketName).setCorsConfiguration([]);

  console.log(`Removed CORS configuration from bucket ${bucketName}`);
}

removeBucketCors().catch(console.error);

Python

Para mais informações, consulte a documentação de referência da API Cloud Storage para Python.

from google.cloud import storage

def remove_cors_configuration(bucket_name):
    """Remove a bucket's CORS policies configuration."""
    # bucket_name = "your-bucket-name"

    storage_client = storage.Client()
    bucket = storage_client.get_bucket(bucket_name)
    bucket.cors = []
    bucket.patch()

    print("Remove CORS policies for bucket {}.".format(bucket.name))
    return bucket

Ruby

Para mais informações, consulte a documentação de referência da API Cloud Storage para Ruby.

def remove_cors_configuration bucket_name:
  # The ID of your GCS bucket
  # bucket_name = "your-unique-bucket-name"

  require "google/cloud/storage"

  storage = Google::Cloud::Storage.new
  bucket = storage.bucket bucket_name

  bucket.cors do |c|
    c.clear
  end

  puts "Remove CORS policies for bucket #{bucket_name}"
end

C#

Para mais informações, consulte a documentação de referência da API Cloud Storage para C#.

No momento, não é possível trabalhar com o CORS usando a biblioteca de cliente C#.

PHP

Para mais informações, consulte a documentação de referência da API Cloud Storage para PHP.

Para trabalhar com as configurações do CORS em um bucket usando o PHP, consulte a documentação de referência do Google\Cloud\Storage\bucket (em inglês).

APIs REST

API JSON

  1. Consiga um token de acesso de autorização do OAuth 2.0 Playground (em inglês). Configure o Playground para usar suas credenciais do OAuth.
  2. Crie um arquivo JSON que contenha o seguinte:

    {
     "cors": []
    }
  3. Use cURL para chamar a API JSON com uma solicitação PATCH bucket:

    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

    Em que:

    • BUCKET_NAME é o nome do bucket. Por exemplo, my-bucket.
    • OAUTH2_TOKEN é o token de acesso gerado na etapa 1;
    • JSON_FILE_NAME é o caminho para o arquivo criado na Etapa 2.

API XML

  1. Consiga um token de acesso de autorização do OAuth 2.0 Playground (em inglês). Configure o Playground para usar suas credenciais do OAuth.
  2. Crie um arquivo XML que contenha o seguinte:

    <CorsConfig></CorsConfig>
  3. Use cURL (em inglês) para chamar a API XML com uma solicitação 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"

    Em que:

    • BUCKET_NAME é o nome do bucket. Por exemplo, my-bucket.
    • OAUTH2_TOKEN é o token de acesso gerado na etapa 1;
    • PROJECT_ID é o ID do projeto associado ao bucket. Por exemplo, my-project.
    • XML_FILE_NAME é o caminho para o arquivo criado na Etapa 2.

Solução de problemas com solicitações do CORS

Se você enfrentar um comportamento inesperado ao acessar buckets do Cloud Storage de uma origem diferente, siga as etapas abaixo:

  1. Use gsutil cors get no bucket de destino para ver a configuração do CORS. Se houver várias entradas de configuração do CORS, verifique se, nas etapas abaixo, os valores da solicitação estão mapeados para valores na mesma entrada de configuração do CORS.

  2. Verifique se você não está fazendo uma solicitação para o endpoint storage.cloud.google.com, que não permite solicitações de CORS. Para mais informações sobre endpoints compatíveis com o CORS, consulte suporte ao CORS do Cloud Storage.

  3. Revise a solicitação e a resposta usando a ferramenta da sua preferência. No navegador Chrome, veja essas informações usando as ferramentas padrão para desenvolvedores:

    1. Clique no menu Ícone do menu do Chrome. na barra de ferramentas do Chrome.
    2. Selecione Mais ferramentas > Ferramentas do desenvolvedor.
    3. Clique na guia Rede.
    4. No seu aplicativo ou na linha de comando, envie a solicitação.
    5. No painel que exibe a atividade da rede, localize a solicitação.
    6. Na coluna Nome, clique no nome que corresponde à solicitação.
    7. Clique na guia Cabeçalhos ou Resposta para ver, respectivamente, os cabeçalhos ou o conteúdo da resposta.

    Se você não estiver vendo a solicitação e a resposta, é possível que o navegador tenha armazenado em cache uma tentativa de simulação de solicitação anterior que falhou. Limpar o cache de seu navegador provavelmente limpará o cache da simulação. Se isso não acontecer, defina MaxAgeSec na configuração do CORS para um valor mais baixo (o valor padrão é 1800, 30 minutos, se não for especificado). Aguarde o tempo do MaxAgeSec antigo e depois faça a solicitação novamente. Assim, será executada uma nova simulação de solicitação que buscará a nova configuração do CORS e limpará as entradas do cache. Após depurar o problema, aumente novamente o valor de MaxAgeSec para reduzir o tráfego de simulação para o bucket.

  4. Certifique-se de que a solicitação tenha um cabeçalho Origin e que o valor do cabeçalho corresponda a pelo menos um dos valores de Origins na configuração do CORS do intervalo. É necessário que o esquema, o host e a porta dos valores se correspondam exatamente. Alguns exemplos de correspondências aceitáveis:

    • http://origin.example.com corresponde a http://origin.example.com:80 (porque 80 é a porta HTTP padrão), mas não corresponde a https://origin.example.com, http://origin.example.com:8080, http://origin.example.com:5151 ou http://sub.origin.example.com.

    • https://example.com:443 corresponde a https://example.com, mas não a http://example.com ou http://example.com:443.

    • http://localhost:8080 corresponde somente a http://localhost:8080, não a http://localhost:5555 ou http://localhost.example.com:8080.

  5. Verifique se o método HTTP da solicitação, no caso de uma solicitação simples, ou o método especificado em Access-Control-Request-Method, no caso de uma solicitação de simulação, corresponde a pelo menos um dos valores de Methods na configuração do CORS do intervalo.

  6. Se essa for uma solicitação de simulação, veja se ela inclui um ou mais cabeçalhos Access-Control-Request-Header. Em caso afirmativo, certifique-se de que cada valor de Access-Control-Request-Header corresponda a um valor ResponseHeader na configuração do CORS do intervalo. Todos os cabeçalhos nomeados em Access-Control-Request-Header precisam estar presentes na configuração do CORS para que a simulação de solicitação tenha êxito e inclua cabeçalhos do CORS na resposta.

A seguir