google-cloud-node: The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.

Hi team, I have spent a lot of time to solve the problem and also spent a lot of time to search the solution on net but every time I failed. The scenario is that

I am using @google-cloud/storage to upload my image on google cloud storage. Everything is fine. Images successfully uploaded on cloud. Now I want to show these images to my users but I didn’t want to give public permission to images. So I created a signed url and trying to download them but everytime I am facing the following problem

<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.
</Message>
<StringToSign>GET 1486639481 /<my bucket name>/<my image name></StringToSign>
</Error>

here is my code

//get signed url
    action: 'read',
        expires: Date.now() + 76000000,
        contentType: 'image/jpeg'
    };
    var file = bucket.file('TestingImage.jpg').getSignedUrl(options, function (error, signedUrl) {
        console.log('signed url...');
        console.log(signedUrl);
    });

But when I put this signed url in browser it give me the error.

I am following the url for uploading image https://googlecloudplatform.github.io/google-cloud-node/#/docs/storage/0.6.0/storage

How ever I can download these image in nodejs using file.download() but I want to view this image on browser

Please guide me when am I wrong.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 13
  • Comments: 15 (3 by maintainers)

Most upvoted comments

The browser will need to set the matching Content Type on the request headers.

As needed. If you provide a content-type, the client (browser) must provide this HTTP header set to the same value. - https://cloud.google.com/storage/docs/access-control/signed-urls

If you remove the content type while creating the signed URL, it should work in the browser.

Hi, there!

I’m facing the same problem but I’ve already removed the content type while creating the signed URL. The interesting fact is that this problem only happens suddenly a few days after the signed URL is created…

The code I’m following is the one below: https://github.com/firebase/functions-samples/blob/master/generate-thumbnail/functions/index.js

Thanks in advance!

For me it was because I was using POST instead of PUT, it’s not just about the ContentType header, the http method also has to match, in golang:

method := "PUT"   // THIS MUST MATCH
expires := time.Now().Add(time.Minute * 10)

url, err := storage.SignedURL(bucket, filename, &storage.SignedURLOptions{
  GoogleAccessID: cfg.Email,
  PrivateKey:     cfg.PrivateKey,
  Method:         method,   
  Expires:        expires,
  ContentType:    "binary/octet-stream",   // NOTE
})

if err != nil {
// ...
}

var client = http.DefaultClient
request, err := http.NewRequest("PUT", url, req.Body)  // we use PUT not POST

if err != nil {
// ....
}

request.Header.Set("Content-Type", "binary/octet-stream")  // this must match
response, err := client.Do(request)

I’m in the same boat, uploaded image’s url works but some days later, getting 403. found suspicious note about expires parameter on the api doc:

A timestamp when this link will expire. Any value given is passed to new Date(). Note: ‘v4’ supports maximum duration of 7 days (604800 seconds) from now.

Greetings folks! If you’re having issues, please open a new issue here: https://github.com/googleapis/nodejs-storage/