Node.js 将文件上载到Amazon S3时出现拒绝访问错误
我正试图上传到s3亚马逊。当我试着在笔记本电脑上运行我使用postman运行node js server创建的api时,它工作得很好,上传起来很容易,没有任何错误,但在部署代码amazon aws后,它给了我“拒绝访问错误”。我认为这与我的节点js代码或CORS策略中的某些CORS设置有关,但我无法理解。 错误消息是: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
"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状态。您是否从策略生成器生成此策略?