Processo de assinatura V4 com ferramentas do Cloud Storage

Nesta página, descrevemos como usar as bibliotecas de cliente do gsutil e do Cloud Storage para criar URLs assinados. Os URLs assinados dão acesso de leitura ou gravação por tempo limitado a um recurso específico do Cloud Storage. Se você quiser criar seu próprio programa para criar URLs assinados, leia Assinatura V4 com seu próprio programa.

Como criar um URL assinado para fazer o download de um objeto

Para criar um URL assinado que consiga um objeto de um bucket, conclua as etapas a seguir:

gsutil

  1. Gere uma nova chave privada ou use uma atual de uma conta de serviço. A chave pode estar no formato JSON ou PKCS12.

    Para mais informações sobre chaves privadas e contas de serviço, consulte Contas de serviço.

  2. Use o comando gsutil signurl, passando o caminho para a chave privada da etapa anterior, bem como o nome do bucket e do objeto.

    Por exemplo, usando uma chave armazenada na pasta Desktop, o comando a seguir gera um URL assinado para que os usuários visualizem o objeto cat.jpeg por 10 minutos.

    gsutil signurl -d 10m Desktop/private-key.json gs://example-bucket/cat.jpeg

    Se bem-sucedida, a resposta será assim:

    URL    HTTP Method    Expiration    Signed URL
    gs://example-bucket/cat.jpeg GET 2018-10-26 15:19:52 https://storage.googleapis.
    com/example-bucket/cat.jpeg?x-goog-signature=2d2a6f5055eb004b8690b9479883292ae74
    50cdc15f17d7f99bc49b916f9e7429106ed7e5858ae6b4ab0bbbdb1a8ccc364dad3a0da2caebd308
    87a70c5b2569d089ceb8afbde3eed4dff5116f0db5483998c175980991fe899fbd2cd8cb813b0016
    5e8d56e0a8aa7b3d7a12ee1baa8400611040f05b50a1a8eab5ba223fe5375747748de950ec7a4dc5
    0f8382a6ffd49941c42498d7daa703d9a414d4475154d0e7edaa92d4f2507d92c1f7e811a7cab64d
    f68b5df4857589259d8d0bdb5dc752bdf07bd162d98ff2924f2e4a26fa6b3cede73ad5333c47d146
    a21c2ab2d97115986a12c28ff37346d6c2ca83e5618ec8ad95632710b489b75c35697d781c38e&
    x-goog-algorithm=GOOG4-RSA-SHA256&x-goog-credential=example%40example-project.
    iam.gserviceaccount.com%2F20181026%2Fus%2Fstorage%2Fgoog4_request&x-goog-date=
    20201026T211942Z&x-goog-expires=3600&x-goog-signedheaders=host

    O URL assinado é a string que começa com https://storage.googleapis.com e provavelmente se estenderá por várias linhas. Este URL pode ser usado por qualquer pessoa para acessar o recurso associado (neste caso, cat.jpeg) no período designado (neste caso, 10 minutos).

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& object_name, std::string const& signing_account) {
  StatusOr<std::string> signed_url = client.CreateV4SignedUrl(
      "GET", std::move(bucket_name), std::move(object_name),
      gcs::SignedUrlDuration(std::chrono::minutes(15)),
      gcs::SigningAccount(signing_account));

  if (!signed_url) throw std::runtime_error(signed_url.status().message());
  std::cout << "The signed url is: " << *signed_url << "\n\n"
            << "You can use this URL with any user agent, for example:\n"
            << "curl '" << *signed_url << "'\n";
}

C#

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


using Google.Cloud.Storage.V1;
using System;
using System.Net.Http;

public class GenerateV4SignedReadUrlSample
{
    public string GenerateV4SignedReadUrl(
        string bucketName = "your-unique-bucket-name",
        string objectName = "your-object-name",
        string credentialFilePath = "my-local-path/my-credential-file-name")
    {
        UrlSigner urlSigner = UrlSigner.FromServiceAccountPath(credentialFilePath);
        // V4 is the default signing version.
        string url = urlSigner.Sign(bucketName, objectName, TimeSpan.FromHours(1), HttpMethod.Get);
        Console.WriteLine("Generated GET signed URL:");
        Console.WriteLine(url);
        Console.WriteLine("You can use this URL with any user agent, for example:");
        Console.WriteLine($"curl '{url}'");
        return url;
    }
}

Go

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

import (
	"fmt"
	"io"
	"io/ioutil"
	"time"

	"cloud.google.com/go/storage"
	"golang.org/x/oauth2/google"
)

// generateV4GetObjectSignedURL generates object signed URL with GET method.
func generateV4GetObjectSignedURL(w io.Writer, bucket, object, serviceAccount string) (string, error) {
	// bucket := "bucket-name"
	// object := "object-name"
	// serviceAccount := "service_account.json"
	jsonKey, err := ioutil.ReadFile(serviceAccount)
	if err != nil {
		return "", fmt.Errorf("ioutil.ReadFile: %v", err)
	}
	conf, err := google.JWTConfigFromJSON(jsonKey)
	if err != nil {
		return "", fmt.Errorf("google.JWTConfigFromJSON: %v", err)
	}
	opts := &storage.SignedURLOptions{
		Scheme:         storage.SigningSchemeV4,
		Method:         "GET",
		GoogleAccessID: conf.Email,
		PrivateKey:     conf.PrivateKey,
		Expires:        time.Now().Add(15 * time.Minute),
	}
	u, err := storage.SignedURL(bucket, object, opts)
	if err != nil {
		return "", fmt.Errorf("storage.SignedURL: %v", err)
	}

	fmt.Fprintln(w, "Generated GET signed URL:")
	fmt.Fprintf(w, "%q\n", u)
	fmt.Fprintln(w, "You can use this URL with any user agent, for example:")
	fmt.Fprintf(w, "curl %q\n", u)
	return u, nil
}

Java

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

import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageException;
import com.google.cloud.storage.StorageOptions;
import java.net.URL;
import java.util.concurrent.TimeUnit;

public class GenerateV4GetObjectSignedUrl {
  /**
   * Signing a URL requires Credentials which implement ServiceAccountSigner. These can be set
   * explicitly using the Storage.SignUrlOption.signWith(ServiceAccountSigner) option. If you don't,
   * you could also pass a service account signer to StorageOptions, i.e.
   * StorageOptions().newBuilder().setCredentials(ServiceAccountSignerCredentials). In this example,
   * neither of these options are used, which means the following code only works when the
   * credentials are defined via the environment variable GOOGLE_APPLICATION_CREDENTIALS, and those
   * credentials are authorized to sign a URL. See the documentation for Storage.signUrl for more
   * details.
   */
  public static void generateV4GetObjectSignedUrl(
      String projectId, String bucketName, String objectName) throws StorageException {
    // String projectId = "my-project-id";
    // String bucketName = "my-bucket";
    // String objectName = "my-object";

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

    // Define resource
    BlobInfo blobInfo = BlobInfo.newBuilder(BlobId.of(bucketName, objectName)).build();

    URL url =
        storage.signUrl(blobInfo, 15, TimeUnit.MINUTES, Storage.SignUrlOption.withV4Signature());

    System.out.println("Generated GET signed URL:");
    System.out.println(url);
    System.out.println("You can use this URL with any user agent, for example:");
    System.out.println("curl '" + url + "'");
  }
}

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.
 * Note: when creating a signed URL, unless running in a GCP environment,
 * a service account must be used for authorization.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The full path of your file inside the GCS bucket, e.g. 'yourFile.jpg' or 'folder1/folder2/yourFile.jpg'
// const fileName = 'your-file-name';

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

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

async function generateV4ReadSignedUrl() {
  // These options will allow temporary read access to the file
  const options = {
    version: 'v4',
    action: 'read',
    expires: Date.now() + 15 * 60 * 1000, // 15 minutes
  };

  // Get a v4 signed URL for reading the file
  const [url] = await storage
    .bucket(bucketName)
    .file(fileName)
    .getSignedUrl(options);

  console.log('Generated GET signed URL:');
  console.log(url);
  console.log('You can use this URL with any user agent, for example:');
  console.log(`curl '${url}'`);
}

generateV4ReadSignedUrl().catch(console.error);

PHP

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

use Google\Cloud\Storage\StorageClient;

/**
 * Generate a v4 signed URL for downloading an object.
 *
 * @param string $bucketName The name of your Cloud Storage bucket.
 * @param string $objectName The name of your Cloud Storage object.
 */
function get_object_v4_signed_url($bucketName, $objectName)
{
    // $bucketName = 'my-bucket';
    // $objectName = 'my-object';

    $storage = new StorageClient();
    $bucket = $storage->bucket($bucketName);
    $object = $bucket->object($objectName);
    $url = $object->signedUrl(
        # This URL is valid for 15 minutes
        new \DateTime('15 min'),
        [
            'version' => 'v4',
        ]
    );

    print('Generated GET signed URL:' . PHP_EOL);
    print($url . PHP_EOL);
    print('You can use this URL with any user agent, for example:' . PHP_EOL);
    print('curl ' . $url . PHP_EOL);
}

Python

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

import datetime

from google.cloud import storage

def generate_download_signed_url_v4(bucket_name, blob_name):
    """Generates a v4 signed URL for downloading a blob.

    Note that this method requires a service account key file. You can not use
    this if you are using Application Default Credentials from Google Compute
    Engine or from the Google Cloud SDK.
    """
    # bucket_name = 'your-bucket-name'
    # blob_name = 'your-object-name'

    storage_client = storage.Client()
    bucket = storage_client.bucket(bucket_name)
    blob = bucket.blob(blob_name)

    url = blob.generate_signed_url(
        version="v4",
        # This URL is valid for 15 minutes
        expiration=datetime.timedelta(minutes=15),
        # Allow GET requests using this URL.
        method="GET",
    )

    print("Generated GET signed URL:")
    print(url)
    print("You can use this URL with any user agent, for example:")
    print("curl '{}'".format(url))
    return url

Ruby

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

def generate_signed_url_v4 bucket_name:, file_name:
  # The ID of your GCS bucket
  # bucket_name = "your-unique-bucket-name"

  # The ID of your GCS object
  # file_name = "your-file-name"

  require "google/cloud/storage"

  storage = Google::Cloud::Storage.new
  storage_expiry_time = 5 * 60 # 5 minutes

  url = storage.signed_url bucket_name, file_name, method: "GET",
                           expires: storage_expiry_time, version: :v4

  puts "Generated GET signed url:"
  puts url
  puts "You can use this URL with any user agent, for example:"
  puts "curl #{url}"
end

Como criar um URL assinado para fazer upload de um objeto

Para criar um URL assinado que possa fazer upload de um objeto para um bucket, conclua as etapas a seguir:

gsutil

  1. Gere uma nova chave privada ou use uma atual de uma conta de serviço. A chave pode estar no formato JSON ou PKCS12.

    Para mais informações sobre chaves privadas e contas de serviço, consulte Contas de serviço.

  2. Use gcloud auth activate-service-account para autenticar com a conta de serviço:

    gcloud auth activate-service-account --key-file KEY_FILE_LOCATION/KEY_FILE_NAME

    Em que:

  3. Use o comando gsutil signurl com a opção -u para fazer referência às credenciais da conta de serviço.

    Por exemplo, o comando a seguir cria um URL assinado que permite aos usuários fazer upload de um arquivo de imagem:

    gsutil signurl -m PUT -d 1h -c CONTENT_TYPE -u gs://BUCKET_NAME/OBJECT_NAME

    Em que:

    • CONTENT_TYPE é o tipo de conteúdo do objeto. Por exemplo, image/png.

    • BUCKET_NAME é o nome do bucket em que o objeto está sendo enviado. Por exemplo, example-bucket.

    • OBJECT_NAME é o nome a ser atribuído ao objeto enviado. Por exemplo, cat.png.

    Se bem-sucedida, a resposta será assim:

    URL    HTTP Method    Expiration    Signed URL
    gs://example-bucket/cat.png PUT 2021-01-09 00:28:11 https://storage.googleapis.
    com/example-bucket/cat.png?x-goog-signature=2d2a6f5055eb004b8690b9479883292ae74
    50cdc15f17d7f99bc49b916f9e7429106ed7e5858ae6b4ab0bbbdb1a8ccc364dad3a0da2caebd308
    87a70c5b2569d089ceb8afbde3eed4dff5086f0db5483998c175980991fe899fbd2cd8cb813b0016
    5e8d56e0a8aa7b3d7215ee1baa8400611040f05b50a1a8eab5ba223fe1375747748de950ec7i6dc5
    0f8382a6ffd4994ac42498d7daa703d9a414d4475154d0e7edaa92d4f2507d92c1f7e8efa7cab64d
    f68b5df48575b9259d8d0bdb5dc752bdf07bd162d98ff2924f2p4a26fa6b3cede73ad5333c47d146
    a21c2ab2d97b15986a12c68ff3734696c2ca83e56b8ec8ad95632710b488b75c35697d781c38e&
    x-goog-algorithm=GOOG4-RSA-SHA256&x-goog-credential=example%40example-project.
    iam.gserviceaccount.com%2F20181026%2Fus%2Fstorage%2Fgoog4_request&x-goog-date=
    20201026T211942Z&x-goog-expires=3600&x-goog-signedheaders=host

    O URL assinado é a string que começa com https://storage.googleapis.com e provavelmente se estenderá por várias linhas. Este URL pode ser usado por qualquer pessoa para fazer upload de um recurso (neste caso, cat.png) ao bucket do Cloud Storage especificado para o período designado (neste caso, 1 hora).

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& object_name, std::string const& signing_account) {
  StatusOr<std::string> signed_url = client.CreateV4SignedUrl(
      "PUT", std::move(bucket_name), std::move(object_name),
      gcs::SignedUrlDuration(std::chrono::minutes(15)),
      gcs::AddExtensionHeader("content-type", "application/octet-stream"),
      gcs::SigningAccount(signing_account));

  if (!signed_url) throw std::runtime_error(signed_url.status().message());
  std::cout << "The signed url is: " << *signed_url << "\n\n"
            << "You can use this URL with any user agent, for example:\n"
            << "curl -X PUT -H 'Content-Type: application/octet-stream'"
            << " --upload-file my-file '" << *signed_url << "'\n";
}

C#

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


using Google.Cloud.Storage.V1;
using System;
using System.Collections.Generic;
using System.Net.Http;

public class GenerateV4UploadSignedUrlSample
{
    public string GenerateV4UploadSignedUrl(
        string bucketName = "your-unique-bucket-name",
        string objectName = "your-object-name",
        string credentialFilePath = "my-local-path/my-credential-file-name")
    {
        UrlSigner urlSigner = UrlSigner.FromServiceAccountPath(credentialFilePath);

        var contentHeaders = new Dictionary<string, IEnumerable<string>>
        {
            { "Content-Type", new[] { "text/plain" } }
        };

        // V4 is the default signing version.
        UrlSigner.Options options = UrlSigner.Options.FromDuration(TimeSpan.FromHours(1));

        UrlSigner.RequestTemplate template = UrlSigner.RequestTemplate
            .FromBucket(bucketName)
            .WithObjectName(objectName)
            .WithHttpMethod(HttpMethod.Put)
            .WithContentHeaders(contentHeaders);

        string url = urlSigner.Sign(template, options);
        Console.WriteLine("Generated PUT signed URL:");
        Console.WriteLine(url);
        Console.WriteLine("You can use this URL with any user agent, for example:");
        Console.WriteLine($"curl -X PUT -H 'Content-Type: text/plain' --upload-file my-file '{url}'");
        return url;
    }
}

Go

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

import (
	"fmt"
	"io"
	"io/ioutil"
	"time"

	"cloud.google.com/go/storage"
	"golang.org/x/oauth2/google"
)

// generateV4PutObjectSignedURL generates object signed URL with PUT method.
func generateV4PutObjectSignedURL(w io.Writer, bucket, object, serviceAccount string) (string, error) {
	// bucket := "bucket-name"
	// object := "object-name"
	// serviceAccount := "service_account.json"
	jsonKey, err := ioutil.ReadFile(serviceAccount)
	if err != nil {
		return "", fmt.Errorf("ioutil.ReadFile: %v", err)
	}
	conf, err := google.JWTConfigFromJSON(jsonKey)
	if err != nil {
		return "", fmt.Errorf("google.JWTConfigFromJSON: %v", err)
	}
	opts := &storage.SignedURLOptions{
		Scheme: storage.SigningSchemeV4,
		Method: "PUT",
		Headers: []string{
			"Content-Type:application/octet-stream",
		},
		GoogleAccessID: conf.Email,
		PrivateKey:     conf.PrivateKey,
		Expires:        time.Now().Add(15 * time.Minute),
	}
	u, err := storage.SignedURL(bucket, object, opts)
	if err != nil {
		return "", fmt.Errorf("storage.SignedURL: %v", err)
	}
	fmt.Fprintln(w, "Generated PUT signed URL:")
	fmt.Fprintf(w, "%q\n", u)
	fmt.Fprintln(w, "You can use this URL with any user agent, for example:")
	fmt.Fprintf(w, "curl -X PUT -H 'Content-Type: application/octet-stream' --upload-file my-file %q\n", u)
	return u, nil
}

Java

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

import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.HttpMethod;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageException;
import com.google.cloud.storage.StorageOptions;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class GenerateV4PutObjectSignedUrl {
  /**
   * Signing a URL requires Credentials which implement ServiceAccountSigner. These can be set
   * explicitly using the Storage.SignUrlOption.signWith(ServiceAccountSigner) option. If you don't,
   * you could also pass a service account signer to StorageOptions, i.e.
   * StorageOptions().newBuilder().setCredentials(ServiceAccountSignerCredentials). In this example,
   * neither of these options are used, which means the following code only works when the
   * credentials are defined via the environment variable GOOGLE_APPLICATION_CREDENTIALS, and those
   * credentials are authorized to sign a URL. See the documentation for Storage.signUrl for more
   * details.
   */
  public static void generateV4GPutObjectSignedUrl(
      String projectId, String bucketName, String objectName) throws StorageException {
    // String projectId = "my-project-id";
    // String bucketName = "my-bucket";
    // String objectName = "my-object";

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

    // Define Resource
    BlobInfo blobInfo = BlobInfo.newBuilder(BlobId.of(bucketName, objectName)).build();

    // Generate Signed URL
    Map<String, String> extensionHeaders = new HashMap<>();
    extensionHeaders.put("Content-Type", "application/octet-stream");

    URL url =
        storage.signUrl(
            blobInfo,
            15,
            TimeUnit.MINUTES,
            Storage.SignUrlOption.httpMethod(HttpMethod.PUT),
            Storage.SignUrlOption.withExtHeaders(extensionHeaders),
            Storage.SignUrlOption.withV4Signature());

    System.out.println("Generated PUT signed URL:");
    System.out.println(url);
    System.out.println("You can use this URL with any user agent, for example:");
    System.out.println(
        "curl -X PUT -H 'Content-Type: application/octet-stream' --upload-file my-file '"
            + url
            + "'");
  }
}

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';

// The full path of your file inside the GCS bucket, e.g. 'yourFile.jpg' or 'folder1/folder2/yourFile.jpg'
// const fileName = 'your-file-name';

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

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

async function generateV4UploadSignedUrl() {
  // These options will allow temporary uploading of the file with outgoing
  // Content-Type: application/octet-stream header.
  const options = {
    version: 'v4',
    action: 'write',
    expires: Date.now() + 15 * 60 * 1000, // 15 minutes
    contentType: 'application/octet-stream',
  };

  // Get a v4 signed URL for uploading file
  const [url] = await storage
    .bucket(bucketName)
    .file(fileName)
    .getSignedUrl(options);

  console.log('Generated PUT signed URL:');
  console.log(url);
  console.log('You can use this URL with any user agent, for example:');
  console.log(
    "curl -X PUT -H 'Content-Type: application/octet-stream' " +
      `--upload-file my-file '${url}'`
  );
}

generateV4UploadSignedUrl().catch(console.error);

PHP

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

use Google\Cloud\Storage\StorageClient;

/**
 * Generate a v4 signed URL for uploading an object.
 *
 * @param string $bucketName The name of your Cloud Storage bucket.
 * @param string $objectName The name of your Cloud Storage object.
 */
function upload_object_v4_signed_url($bucketName, $objectName)
{
    // $bucketName = 'my-bucket';
    // $objectName = 'my-object';

    $storage = new StorageClient();
    $bucket = $storage->bucket($bucketName);
    $object = $bucket->object($objectName);
    $url = $object->signedUrl(
        # This URL is valid for 15 minutes
        new \DateTime('15 min'),
        [
            'method' => 'PUT',
            'contentType' => 'application/octet-stream',
            'version' => 'v4',
        ]
    );

    print('Generated PUT signed URL:' . PHP_EOL);
    print($url . PHP_EOL);
    print('You can use this URL with any user agent, for example:' . PHP_EOL);
    print("curl -X PUT -H 'Content-Type: application/octet-stream' " .
        '--upload-file my-file ' . $url . PHP_EOL);
}

Python

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

import datetime

from google.cloud import storage

def generate_upload_signed_url_v4(bucket_name, blob_name):
    """Generates a v4 signed URL for uploading a blob using HTTP PUT.

    Note that this method requires a service account key file. You can not use
    this if you are using Application Default Credentials from Google Compute
    Engine or from the Google Cloud SDK.
    """
    # bucket_name = 'your-bucket-name'
    # blob_name = 'your-object-name'

    storage_client = storage.Client()
    bucket = storage_client.bucket(bucket_name)
    blob = bucket.blob(blob_name)

    url = blob.generate_signed_url(
        version="v4",
        # This URL is valid for 15 minutes
        expiration=datetime.timedelta(minutes=15),
        # Allow PUT requests using this URL.
        method="PUT",
        content_type="application/octet-stream",
    )

    print("Generated PUT signed URL:")
    print(url)
    print("You can use this URL with any user agent, for example:")
    print(
        "curl -X PUT -H 'Content-Type: application/octet-stream' "
        "--upload-file my-file '{}'".format(url)
    )
    return url

Ruby

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

def generate_upload_signed_url_v4 bucket_name:, file_name:
  # The ID of your GCS bucket
  # bucket_name = "your-unique-bucket-name"

  # The ID of your GCS object
  # file_name = "your-file-name"

  require "google/cloud/storage"

  storage = Google::Cloud::Storage.new
  storage_expiry_time = 5 * 60 # 5 minutes

  url = storage.signed_url bucket_name, file_name, method: "PUT",
                           expires: storage_expiry_time, version: :v4,
                           headers: { "Content-Type" => "text/plain" }
  puts "Generated PUT signed URL:"
  puts url
  puts "You can use this URL with any user agent, for example:"
  puts "curl -X PUT -H 'Content-Type: text/plain' --upload-file my-file '#{url}'"
end

A seguir