我的本地计算机上有一个NodeJS应用程序。我正在尝试使用Amazon S3服务进行设置,但遗憾的是,它不起作用。 我可以获得签名的URL,但是在上传文件时,AWS返回Forbidden 403(多次丢弃连接,但在我从CORS删除了超时选项后停止了)
到目前为止我做了什么:
使用以下政策创建新用户:
{
"Statement": [
{
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}
]
}
为此用户创建了新的访问密钥
将存储桶的CORS更新为
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
更新了存储分区策略
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "111",
"Effect": "Allow",
"Principal": {
"AWS": "my-user-id-number"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
在NodeJS中创建了对签名网址的调用(使用Express)
aws.config.accessKeyId = process.env.AWS_ACCESS_KEY_ID;
aws.config.secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
router.get('/sign-s3', function (req, res) {
var s3 = new aws.S3();
var fileName = req.query.fileName;
var fileType = req.query.fileType;
var s3Params = {
Key: fileName,
Bucket: process.env.S3_BUCKET_NAME,
Expires: 600,
ContentType: fileType,
ACL: 'public-read'
};
s3.getSignedUrl('putObject', s3Params, function (err, data) {
if (err) {
console.log(err);
return res.end();
}
var returnData = {
signedRequest: data,
url: 'https://${S3_BUCKET_NAME}.s3.amazonaws.com/${fileName}'
};
res.write(JSON.stringify(returnData));
res.end();
});
});
上传文件
$http({
method: 'GET',
url: '/aws/sign-s3',
params: data
}).then(function (response) {
var fd = new FormData();
fd.append("file", file);
$http({
method: 'PUT',
url: response.data.signedRequest,
data: fd
}).then(function (response) {
defer.resolve(response);
}, function (err) {
defer.reject(err);
});
}, function (err) {
defer.reject(err);
});
还有一件事我不明白:我创建了一个用户并授予它访问s3的权限,但我无法将用户分配给存储桶权限。它在访问策略中缺少某些内容吗?
提前感谢任何提示!
答案 0 :(得分:0)
我已经想通了。
首先,我生成了新的访问密钥以确保这些密钥正确无误。 其次,我更新了我的上传请求,设置内容类型和仅序列化文件,而不是带文件的FormData。
所以上传请求看起来
$http({
method: 'PUT',
url: response.data.signedRequest,
data: file,
headers: {'Content-type': file.type}
}).then(function (response) {
defer.resolve(response);
}, function (err) {
defer.reject(err);
});