使用 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 设置:


    {
        "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"。这让我意识到我的访问密钥一开始甚至没有被调用。