实际测试用例代码: https://github.com/HenrikJoreteg/google-cloud-signedurl-test-case
我尝试为我的API添加功能,以返回已签名的网址,以便从客户端直接上传到Google云端存储。
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'/>
我选择了一个文件,然后我尝试将其发布到我的服务器端脚本生成的URL中,如下所示: / p>
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密钥文件,以确保它是最新的并具有该存储桶的适当权限,并且在生成签名网址时我不会收到任何错误或任何内容。
客户端代码似乎正确启动上传(我看到进度更新已注销)然后我收到403错误。文件名匹配,内容类型似乎与预期值匹配,到期似乎合理。
官方SDK生成了URL,所以看起来好像没问题。
我被困住了,任何帮助都表示赞赏。
答案 0 :(得分:4)
正如Philip Roberts所指出的那样,在我的github repo中包含@LatentFlip的情况下,在签名中添加了一个内容类型来处理它。
此外,听起来像谷歌人会更新文档/错误更有帮助:https://github.com/GoogleCloudPlatform/google-cloud-node/issues/1695