S3 签名在 getSignedUrl 服务器端节点上不匹配



我正在尝试使用 angular4 中的预签名 url 将视频文件放入我的存储桶。

节点:

let s3 = new AWS.S3();
s3.config.update({
accessKeyId: process.env.VIDEO_ACCESS_KEY,
secretAccessKey: process.env.VIDEO_SECRET_KEY
})
let videoId = await Video.createVideo()
let params = {
ACL: "public-read",
Bucket: process.env.BUCKET_NAME,
ContentType: 'video/mp4',
Expires: 100,
Key: req.jwt.username+"/"+videoId,
}
return s3.getSignedUrl('putObject', params, function (err, url) {
if(!err) {
console.log(url);
res.status(200);
res.json({
url: url,
reference: `${process.env.BUCKET_NAME}/${req.jwt.username}/${videoId}`,
acl: params.ACL,
bucket: params.Bucket,
key: params.Key,
contentType: params.ContentType,
});
} else {
console.log(err);
res.status(400);
res.json({
message: "Something went wrong"
})
}
});

这成功地为我生成了一个 url,我尝试在前端的 post 请求中使用它。

角:

this.auth.fileUpload().subscribe((result) => {
console.log(result["key"], result["acl"], result["bucket"], result["contentType"])
if(!result["message"]) {
let formData = new FormData();
formData.append('file', file.files[0]);
const httpOptions = {
headers: new HttpHeaders({
"Key": result["key"],
"ACL": result["acl"],
"Bucket": result["bucket"],
"Content-Type": result["contentType"],
})
};
this.http.post(result["url"], formData, httpOptions ).subscribe((response) => {
console.log("response");
console.log(response);
let reference = `https://s3.amazonaws.com/${result["reference"]}`
this.auth.makeVideo(result["reference"]).subscribe((result) => {
console.log(result);
});
}, (error) => {
console.log("error");
console.log(error);
})

但这会产生错误。

SignatureDoesNotMatch
The request signature we calculated does not match the signature you provided. Check your key and signing method

这是我生成的网址

https://MY_BUCKET_HERE.s3.amazonaws.com/admin/87f314f1-9f2e-462e-84ff-25cba958ac50?AWSAccessKeyId=MY_ACCESS_KEY_HERE&Content-Type=video%2Fmp4&Expires=1520368428&Signature=Ks0wfzGyXmBTiAxGkHNgcYblpX8%3D&x-amz-acl=public-read

我很确定我只是犯了一个简单的错误,但我一辈子都想不通。我需要对我的标头执行某些操作吗?我需要更改阅读帖子文件的方式吗?我已经让它与带有 FormData 的公共存储桶和一个没有标头的简单发布请求一起使用,但现在我正在使用策略和私有存储桶,我的理解要少得多。我做错了什么?

如果为 PutObject 生成预签名 URL,则应使用 HTTP PUT 方法将文件上传到该预签名 URL。POST 方法不起作用(它是为浏览器上传而设计的)。

此外,不要在调用 PUT 时提供 HTTP 标头。生成预签名 URL 时应提供它们,但在使用预签名 URL 时不提供它们。

最新更新