Node.js 将文件上载到Amazon S3时出现拒绝访问错误

Node.js 将文件上载到Amazon S3时出现拒绝访问错误,node.js,amazon-web-services,amazon-s3,Node.js,Amazon Web Services,Amazon S3,我正试图上传到s3亚马逊。当我试着在笔记本电脑上运行我使用postman运行node js server创建的api时,它工作得很好,上传起来很容易,没有任何错误,但在部署代码amazon aws后,它给了我“拒绝访问错误”。我认为这与我的节点js代码或CORS策略中的某些CORS设置有关,但我无法理解。 错误消息是: "error": { "message": "Access Denied", &quo

我正试图上传到s3亚马逊。当我试着在笔记本电脑上运行我使用postman运行node js server创建的api时,它工作得很好,上传起来很容易,没有任何错误,但在部署代码amazon aws后,它给了我“拒绝访问错误”。我认为这与我的节点js代码或CORS策略中的某些CORS设置有关,但我无法理解。 错误消息是:

"error": {
        "message": "Access Denied",
        "code": "AccessDenied",
        "region": null,
        "time": "2020-11-14T08:50:08.334Z",
        "requestId": "47A4609E86E45A5B",
        "extendedRequestId": "0e9FxXDR6UCpZRFDotRu+Xc4ZQq+3HlzO1jlSeGaQN5K6nrnuFWp48l08HSC9ZM3DsoiBMJpEkg=",
        "statusCode": 403,
        "retryable": false,
        "retryDelay": 113.70205711590269,
        "storageErrors": []
    }
共享以下代码: App.js代码如下:

const app = express();

var corsOptions = {
  //origin: "http://localhost:1111",
  origin: "*"
};

app.use(cors(corsOptions));

const s3 = new aws.S3({
    accessKeyId: process.env.s3accessKeyId,
    secretAccessKey: process.env.s3secretAccessKey,
  Bucket: process.env.s3Bucket + process.env.APP_ENV
});

console.log("Bucket to upload is: " , process.env.s3Bucket + process.env.APP_ENV);
//store to s3 storage in Test/Stage/Prod
const storageS3 = multerS3({
  s3: s3,
  bucket: process.env.s3Bucket + process.env.APP_ENV,
  acl: 'public-read',
  key: function (req, file, cb) {
    cb( null, path.basename(file.fieldname, path.extname( file.originalname ) ) + '-' + Date.now() + path.extname( file.originalname ) )
  }
});

//store to local disk storage in dev env only
const storageDev = multer.diskStorage({
   destination: function (req, file, cb) {
    cb(null, "uploads/");
  },
  filename: function (req, file, cb) {
    cb(
      null,
      `${file.fieldname}_${Date.now()}${path.extname(file.originalname)}`
    );
  },
});

const fileFilter = (req, file, cb) => {
  //reject a file
  if (
    file.mimetype === "image/jpeg" ||
    file.mimetype === "image/png" ||
    file.mimetype === "application/pdf"
  ) {
    cb(null, true);
  } else {
    cb(new Error("Please select png, jpeg or pdf format"), false);
    console.log("Not correct file type");
  }
};

var storage;
if(process.env.storage == 'storageDev'){
  storage = storageDev
}else if(process.env.storage == 'storageS3'){
  storage = storageS3
}

console.log("Env in use to upload is :", process.env.storage );

app.use(
  multer({
   storage: storage,   // get the storage info from .env
   limits: { fileSize: 1000000000 },
    fileFilter: fileFilter,
  }).fields([
    {
      name: "foodImage",
      maxCount: 1,
    }
  ])
);

app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*"); // if we dont want all we can just add codepen.io
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE"); // add whatever we want
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); // add whatever header we want
  next();
});
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AddCannedAcl",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::825013297360:user/bvuploaduser"
            },
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::bvuploadbucket/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "public-read"
                }
            }
        }
    ]
}
桶策略如下:

const app = express();

var corsOptions = {
  //origin: "http://localhost:1111",
  origin: "*"
};

app.use(cors(corsOptions));

const s3 = new aws.S3({
    accessKeyId: process.env.s3accessKeyId,
    secretAccessKey: process.env.s3secretAccessKey,
  Bucket: process.env.s3Bucket + process.env.APP_ENV
});

console.log("Bucket to upload is: " , process.env.s3Bucket + process.env.APP_ENV);
//store to s3 storage in Test/Stage/Prod
const storageS3 = multerS3({
  s3: s3,
  bucket: process.env.s3Bucket + process.env.APP_ENV,
  acl: 'public-read',
  key: function (req, file, cb) {
    cb( null, path.basename(file.fieldname, path.extname( file.originalname ) ) + '-' + Date.now() + path.extname( file.originalname ) )
  }
});

//store to local disk storage in dev env only
const storageDev = multer.diskStorage({
   destination: function (req, file, cb) {
    cb(null, "uploads/");
  },
  filename: function (req, file, cb) {
    cb(
      null,
      `${file.fieldname}_${Date.now()}${path.extname(file.originalname)}`
    );
  },
});

const fileFilter = (req, file, cb) => {
  //reject a file
  if (
    file.mimetype === "image/jpeg" ||
    file.mimetype === "image/png" ||
    file.mimetype === "application/pdf"
  ) {
    cb(null, true);
  } else {
    cb(new Error("Please select png, jpeg or pdf format"), false);
    console.log("Not correct file type");
  }
};

var storage;
if(process.env.storage == 'storageDev'){
  storage = storageDev
}else if(process.env.storage == 'storageS3'){
  storage = storageS3
}

console.log("Env in use to upload is :", process.env.storage );

app.use(
  multer({
   storage: storage,   // get the storage info from .env
   limits: { fileSize: 1000000000 },
    fileFilter: fileFilter,
  }).fields([
    {
      name: "foodImage",
      maxCount: 1,
    }
  ])
);

app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*"); // if we dont want all we can just add codepen.io
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE"); // add whatever we want
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); // add whatever header we want
  next();
});
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AddCannedAcl",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::825013297360:user/bvuploaduser"
            },
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::bvuploadbucket/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "public-read"
                }
            }
        }
    ]
}
CORS政策:

[
    {
        "AllowedHeaders": [
            "Authorization"
        ],
        "AllowedMethods": [
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "x-amz-server-side-encryption",
            "x-amz-request-id",
            "x-amz-id-2"
        ],
        "MaxAgeSeconds": 3000
    }
]

我还关闭了“阻止公共访问”功能

有人能帮我一下吗您用什么替换您的cors配置“ExposeHeaders”:[“x-amz-server-side-encryption”,“x-amz-request-id”,“x-amz-id-2”`从这个到这个
“ExposeHeaders”:[],
并请检查您的bucket策略,当bucket不可公开访问时,通常会给出403状态。您是否从策略生成器生成此策略?