davidkomer
davidkomer

Reputation: 3088

CORS with SignedURL

How can I use the SignedURL returned from the Go API with CORS?

CURRENT SETUP:

Bucket config

gsutil cors get gs://example-bucket

returns:

[{
  "maxAgeSeconds": 1, 
  "method": ["GET", "HEAD", "PUT", "DELETE", "POST", "OPTIONS"],
  "origin": ["http://example.com", "https://example.com", "http://localhost:4000"], 
  "responseHeader": ["Origin", "Accept", "X-Requested-With", "Authorization", "Content-Type", "Content-Length", "Accept-Encoding", "X-CSRF-Token"
]}]

Go API call

acc, _ := appengine.ServiceAccount(ctx)

signedUrl, err := storage.SignedURL(
        "example-bucket",
        fileName,
        &storage.SignedURLOptions{
            GoogleAccessID: acc,
            SignBytes: func(b []byte) ([]byte, error) {
                _, signedBytes, signingError := appengine.SignBytes(ctx, b)
                return signedBytes, signingError
            },
            Method:      "PUT",
            ContentType: contentType,
            Expires:     time.Now().Add(1 * time.Hour),
        })

JS XHR

Uses the SignedURL from Go, i.e. xhr.open("PUT", signedUrl);

EXTRA NOTES

The SignedURL is generated by the Go API always starts with https://storage.googleapis.com/example-bucket/fileName... elsewhere I've read that it should be www.googleapis.com/storage but I don't think this is the problem, surely the url returned from the official API is correct.

I can see that the request headers include:

So it seems it ticks off all the boxes of the required header...

Upvotes: 2

Views: 289

Answers (1)

davidkomer
davidkomer

Reputation: 3088

On the JS side, I was setting additional metadata for the file uploads via the X-Upload-Content-Type header.

Since this header was not in the CORS config, requests were failing.

By adding that header into the config (e.g. the responseHeader list supplied to gsutil cors set config file), everything is working exactly as described in the question :)

Upvotes: 3

Related Questions