简体   繁体   English

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

[英]Create signed URLs for Google Cloud Storage with node.js for direct upload from browser

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

I'm trying to add ability for my API to return signed URLs for direct upload to Google Cloud Storage from the client. 我正在尝试为我的API添加功能,以返回已签名的网址,以便从客户端直接上传到Google云端存储。

Serverside, I'm using the gcloud SDK for this: Serverside,我正在使用gcloud SDK:

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)
  }
})

Then in the browser I've got an <input type='file'/> that I've selected a file with, then I attempt to post it to the URL generated from my server-side script like this: 然后在浏览器中我有一个<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');

What happens? 怎么了?

Response is: 回应是:

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

I've re-downloaded the JSON key file to make sure it's current and has proper permissions to that bucket and I don't get any errors or anything when generating the signed URL. 我已经重新下载了JSON密钥文件,以确保它是最新的并且具有该存储桶的适当权限,并且在生成签名URL时我不会收到任何错误或任何内容。

The clientside code appears to properly initiate an upload (I see progress updates logged out) then I get the 403 error above. 客户端代码似乎正确启动上传(我看到进度更新已注销)然后我收到403错误。 Filenames match, content-types seem to match expected values, expiration seems reasonable. 文件名匹配,内容类型似乎与预期值匹配,到期似乎合理。

The official SDK generated the URL, so it seems like it'd be ok. 官方SDK生成了URL,所以它似乎没问题。

I'm stuck, any help appreciated. 我被卡住,任何帮助表示赞赏。

As was pointed out by Philip Roberts, aka @LatentFlip on my github repo containing this case, adding a content-type to the signature took care of it. 正如Philip Roberts所指出的,在我的github repo中包含此案例的@LatentFlip,在签名中添加内容类型可以解决它。

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

Also, it sounds like the Google folks are going to update docs/error to be a bit more helpful: https://github.com/GoogleCloudPlatform/google-cloud-node/issues/1695 此外,听起来谷歌人会更新文档/错误更有帮助: https//github.com/GoogleCloudPlatform/google-cloud-node/issues/1695

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM