使用 Multer-S3 将文件上传到 AWS-S3 存储桶时出现 'Access Denied' 错误
Getting an 'Access Denied' error when using Multer-S3 to upload file to AWS-S3 Bucket
我一直在尝试使用 Multer-S3 从我的 express 后端应用程序上传文件,但我收到 'Access Denied' 错误。打印出错误给我这个:
{
"success": false,
"errors": {
"title": "File Upload Error",
"detail": "Access Denied",
"error": {
"message": "Access Denied",
"code": "AccessDenied",
"region": null,
"time": "2021-06-26T16:40:47.074Z",
"requestId": "7W7EMNWNFWTPNHHG",
"extendedRequestId": "9tC2dSn8Zu6dplJxxUVIx3Zdr4mCk7ZVg0RcayXHHO86hTIZdO/9YZKsUKwn1ir0AeUg50Y/c94=",
"statusCode": 403,
"retryable": false,
"retryDelay": 76.37236671132325,
"storageErrors": []
}
}
}
我的 AWS 设置:
- 我有一个 'Block all public access' 开启
的 AWS S3 存储桶
- S3 存储桶没有任何策略或 CORS 配置
- 我创建了一个新的 IAM 用户,并附加了我创建的策略。这是政策:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::test-bucket/*"
}
]
}
其中 'test-bucket' 是我的存储桶的名称。
用户也设置了编程访问权限,我已检查访问密钥是否已更新且处于活动状态。
据我了解,此策略将允许我的 IAM 用户在我的 s3 存储桶中放置、获取和删除对象,即使 public 无法访问它。我也不需要进行任何进一步的配置,例如设置 CORS。
我的代码:
route.js
router.post('/upload', uploadController.uploadToS3);
uploadController.js
const upload = require("../util/s3");
const singleUpload = upload.single("myfile");
exports.uploadToS3 = (req, res, next) => {
singleUpload(req, res, function (err) {
if (err) {
return res.json({
success: false,
errors: {
title: "File Upload Error",
detail: err.message,
error: err
}
})
}
})
};
s3.js
const S3 = require('aws-sdk/clients/s3');
const multer = require("multer");
const multerS3 = require("multer-s3");
bucket_name = process.env.AWS_BUCKET_NAME;
bucket_region = process.env.AWS_BUCKET_REGION;
aws_access_key = process.env.AWS_ACCESS_KEY;
aws_secret_key = process.env.AWS_SECRET_KEY;
const s3 = new S3({
bucket_region,
aws_access_key,
aws_secret_key
})
const upload = multer({
storage: multerS3({
s3: s3,
bucket: bucket_name,
acl: 'private',
metadata: function (req, file, cb) {
cb(null, { fieldName: file.fieldname });
},
key: function (req, file, cb) {
cb(null, file.originalname);
}
})
});
我已经尝试了一些网上建议的解决方案,例如为存储桶本身添加策略,或者设置 CORS 配置。
我什至尝试将我的 IAM 用户策略更改为 S3FullAccess。即便如此,我仍然收到拒绝访问错误。
我按照这个 Youtube 视频教程进行了 AWS 设置:https://www.youtube.com/watch?v=NZElg91l_ms&t=900s&ab_channel=SamMeech-Ward
似乎没有人面临同样的问题...
非常感谢任何帮助,谢谢!
我已经设法解决了我的问题。事实证明这是一个非常愚蠢的错误,与我的 IAM 策略完全无关。问题出在我的 s3.js 代码中,当我创建 s3 对象时:
const s3 = new S3({
bucket_region,
aws_access_key,
aws_secret_key
})
根据 AWS S3 SDK 文档 (https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html),正确的构造函数参数应该是:
const s3 = new S3({
region,
accessKeyId,
secretAccessKey
})
这样,我就可以使用我描述的 AWS 设置上传到我的存储桶。
我之所以注意到这一点是因为我意识到我的 IAM 用户 'Access Key' 部分中的 'Last Used' 列不断显示 "N/A"。这让我意识到我的访问密钥一开始甚至没有被调用。
我一直在尝试使用 Multer-S3 从我的 express 后端应用程序上传文件,但我收到 'Access Denied' 错误。打印出错误给我这个:
{
"success": false,
"errors": {
"title": "File Upload Error",
"detail": "Access Denied",
"error": {
"message": "Access Denied",
"code": "AccessDenied",
"region": null,
"time": "2021-06-26T16:40:47.074Z",
"requestId": "7W7EMNWNFWTPNHHG",
"extendedRequestId": "9tC2dSn8Zu6dplJxxUVIx3Zdr4mCk7ZVg0RcayXHHO86hTIZdO/9YZKsUKwn1ir0AeUg50Y/c94=",
"statusCode": 403,
"retryable": false,
"retryDelay": 76.37236671132325,
"storageErrors": []
}
}
}
我的 AWS 设置:
- 我有一个 'Block all public access' 开启 的 AWS S3 存储桶
- S3 存储桶没有任何策略或 CORS 配置
- 我创建了一个新的 IAM 用户,并附加了我创建的策略。这是政策:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::test-bucket/*"
}
]
}
其中 'test-bucket' 是我的存储桶的名称。
用户也设置了编程访问权限,我已检查访问密钥是否已更新且处于活动状态。
据我了解,此策略将允许我的 IAM 用户在我的 s3 存储桶中放置、获取和删除对象,即使 public 无法访问它。我也不需要进行任何进一步的配置,例如设置 CORS。
我的代码:
route.js
router.post('/upload', uploadController.uploadToS3);
uploadController.js
const upload = require("../util/s3");
const singleUpload = upload.single("myfile");
exports.uploadToS3 = (req, res, next) => {
singleUpload(req, res, function (err) {
if (err) {
return res.json({
success: false,
errors: {
title: "File Upload Error",
detail: err.message,
error: err
}
})
}
})
};
s3.js
const S3 = require('aws-sdk/clients/s3');
const multer = require("multer");
const multerS3 = require("multer-s3");
bucket_name = process.env.AWS_BUCKET_NAME;
bucket_region = process.env.AWS_BUCKET_REGION;
aws_access_key = process.env.AWS_ACCESS_KEY;
aws_secret_key = process.env.AWS_SECRET_KEY;
const s3 = new S3({
bucket_region,
aws_access_key,
aws_secret_key
})
const upload = multer({
storage: multerS3({
s3: s3,
bucket: bucket_name,
acl: 'private',
metadata: function (req, file, cb) {
cb(null, { fieldName: file.fieldname });
},
key: function (req, file, cb) {
cb(null, file.originalname);
}
})
});
我已经尝试了一些网上建议的解决方案,例如为存储桶本身添加策略,或者设置 CORS 配置。
我什至尝试将我的 IAM 用户策略更改为 S3FullAccess。即便如此,我仍然收到拒绝访问错误。
我按照这个 Youtube 视频教程进行了 AWS 设置:https://www.youtube.com/watch?v=NZElg91l_ms&t=900s&ab_channel=SamMeech-Ward 似乎没有人面临同样的问题...
非常感谢任何帮助,谢谢!
我已经设法解决了我的问题。事实证明这是一个非常愚蠢的错误,与我的 IAM 策略完全无关。问题出在我的 s3.js 代码中,当我创建 s3 对象时:
const s3 = new S3({
bucket_region,
aws_access_key,
aws_secret_key
})
根据 AWS S3 SDK 文档 (https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html),正确的构造函数参数应该是:
const s3 = new S3({
region,
accessKeyId,
secretAccessKey
})
这样,我就可以使用我描述的 AWS 设置上传到我的存储桶。
我之所以注意到这一点是因为我意识到我的 IAM 用户 'Access Key' 部分中的 'Last Used' 列不断显示 "N/A"。这让我意识到我的访问密钥一开始甚至没有被调用。