使用node.js为Google云端存储创建已签名的网址,以便从浏览器直接上传

Hen*_*teg 7 javascript node.js google-cloud-storage

实际的测试用例代码: https ://github.com/HenrikJoreteg/google-cloud-signedurl-test-case

我正在尝试为我的API添加功能,以返回已签名的网址,以便从客户端直接上传到Google云端存储.

Serverside,我正在使用gcloudSDK:

const gcloud = require('gcloud')

const gcs = gcloud.storage({
  projectId: 'my project',
  keyFilename: __dirname + '/path/to/JSON/file.json'
})
const bucket = gcs.bucket('bucket-name')

bucket.file('IMG_2540.png').getSignedUrl({
 action: 'write',
 expires: Date.now() + 60000
}, (error, signedUrl) => {
  if (error == null) {
    console.log(signedUrl)
  }
})
Run Code Online (Sandbox Code Playgroud)

然后在浏览器中我有一个<input type='file'/>我选择了一个文件,然后我尝试将它发布到我的服务器端脚本生成的URL,如下所示:

function upload(blobOrFile, url) {
  var xhr = new XMLHttpRequest();
  xhr.open('PUT', url, true);
  xhr.onload = function(e) {
    console.log('DONE!')
  };
  xhr.upload.onprogress = function(e) {
    if (e.lengthComputable) {
      console.log((e.loaded / e.total) * 100)
    }
  };

  xhr.send(blobOrFile);
}

// grab the `File` object dropped (which incidentally
// matches the file name used when generating the signed URL 
upload($('[name=file]').files[0], 'URL GENERATED FROM SERVER-SIDE SCRIPT HERE');
Run Code Online (Sandbox Code Playgroud)

怎么了?

回应是:

<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>PUT

image/png
1476631908
/bucket-name/IMG_2540.png</StringToSign>
</Error>
Run Code Online (Sandbox Code Playgroud)

我已经重新下载了JSON密钥文件,以确保它是最新的并且具有该存储桶的适当权限,并且在生成签名URL时我不会收到任何错误或任何内容.

客户端代码似乎正确启动上传(我看到进度更新已注销)然后我得到403错误.文件名匹配,内容类型似乎与预期值匹配,到期似乎合理.

官方SDK生成了URL,所以它似乎没问题.

我被卡住,任何帮助表示赞赏.

Hen*_*teg 6

正如菲利普·罗伯茨 (Philip Roberts) 所指出的,我的 github 存储库中包含此案例,又名 @LatentFlip,向签名添加内容类型可以解决这个问题。

https://github.com/HenrikJoreteg/google-cloud-signedurl-test-case/pull/1/commits/84290918e7b82dd8c1f22ffcd2c7cdc06b08d334

此外,听起来 Google 的人会更新 docs/error 以提供更多帮助:https : //github.com/GoogleCloudPlatform/google-cloud-node/issues/1695