Reputation: 3088
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:
access-control-request-headers: content-type,x-upload-content-type
access-control-request-method: PUT
origin: http://localhost:4000
So it seems it ticks off all the boxes of the required header...
Upvotes: 2
Views: 289
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