使用已签名投递策略将对象投递到GCS时出错



我正在尝试创建一个签名策略,供用户在谷歌云存储上上传文件。

我在这里面临的问题是文件名,我希望用户在上传时提供文件名,如GCS官方文件中所述,如果你想从用户那里提供文件名为${filename},这不起作用,因为我收到以下错误:

<?xml version='1.0' encoding='UTF-8'?>
<Error>
<Code>InvalidPolicyDocument</Code>
<Message>The content of the form does not meet the conditions specified in the policy document.</Message>
<Details>Failed condition: {"key":"${filename}"}</Details>
</Error>

我已经尝试过用S3的createPresignedPost方法做同样的操作,它运行得很好。

参考:https://cloud.google.com/storage/docs/xml-api/post-object-forms

如有任何帮助,我们将不胜感激。

从GCS:生成策略的My Node.js代码

const { Storage } = require('@google-cloud/storage');
const storage = new Storage();
generateSignedPolicy = () => {
const bucket = 'some-bucket';
const file = storage.bucket(bucket).file("someFolder/${filename}");
const options = {
expires: Date.now() + (1000 * 300),
conditions : [
{ bucket : bucket },
]
};
return new Promise((resolve, reject) => {
file.generateSignedPostPolicyV4(options)
.then(([res]) => resolve(res))
.catch(error => reject(error))
})
} 

使用上述代码生成的策略:

{
"url": "https://storage.googleapis.com/some-bucket/",
"fields": {
"key": "someFolder/${filename}",
"x-goog-date": "20221015T212358Z",
"x-goog-credential": "credential",
"x-goog-algorithm": "GOOG4-RSA-SHA256",
"policy": "policy",
"x-goog-signature": "signature"
}
}

错误详细信息显示:Failed condition: {"key":"${filename}"}

我看了上面写的代码,发现您正试图将一个模板变量放入一个普通字符串中。只能在模板字符串中使用${XXX}。

const file = storage.bucket(bucket).file("${filename}");

应为:

const file = storage.bucket(bucket).file(`${filename}`);

由于您没有修改任何关于文件名的内容,您可以将其简化为:

const file = storage.bucket(bucket).file(filename);

当考虑变量文件名时,此代码似乎有效:

const { Storage } = require('@google-cloud/storage');
const bucket = 'my-bucket';
const storage = new Storage();
async function generateSignedPolicy() {
const file = storage
.bucket(bucket)
.file("someFolder/${filename}");

const [response] = await file.generateSignedPostPolicyV4({
expires: Date.now() + (1000 * 300),
conditions: [],
fields: {
bucket,
acl: 'private',
}
});
// console.log(response);
// Create an HTML form with the provided policy
let output = `<form action="${response.url}" method="POST" enctype="multipart/form-data">n`;
// Include all fields returned in the HTML form as they're required
for (const name of Object.keys(response.fields)) {
const value = response.fields[name];
output += `  <input name="${name}" value="${value}" type="hidden"/>n`;
}
output += '  <input type="file" name="file"/><br />n';
output += '  <input type="submit" value="Upload File"/><br />n';
output += '</form>';
console.log(output);
// Copy file contents to an HTML file and open that file in your browser, select a file, and upload
// There will be a 204 response and the file will be uploaded in someFolder
} 
generateSignedPolicy().catch((err) => {
console.error(err);
})

我删除了所有条件,并将bucket设置为字段。

相关内容

  • 没有找到相关文章