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

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

我正在尝试添加API的function,以便将签名的URL从客户端直接上传到Google Cloud Storage。

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

然后在浏览器中,我有一个<input type='file'/>我select了一个文件,然后我试图把它张贴到从我的服务器端脚本生成的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'); 

怎么了?

回应是:

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

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

客户端代码似乎正确启动上传(我看到进度更新登出),然后我得到上面的403错误。 文件名匹配,内容types似乎匹配预期值,过期似乎是合理的。

官方的SDK生成的url,所以它似乎是没事的。

我卡住了,任何帮助表示赞赏。

正如菲利普·罗伯茨(Philip Roberts)所指出的,也就是我的github回购中的@LatentFlip(包含这种情况),在签名中添加一个内容types来处理它。

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

另外,这听起来像谷歌的人们将更新文档/错误更有帮助: https : //github.com/GoogleCloudPlatform/google-cloud-node/issues/1695