生产环境下上传至AWS S3桶时出现访问拒绝错误
问题分析与解决方案
核心问题定位
访问拒绝错误主要源于代码参数名错误、环境变量拼写失误、IAM权限配置不当,以及SDK版本升级后的适配问题。
1. 修复代码中的关键错误
AWS SDK V2 代码修正
当前V2代码中S3客户端初始化的凭证参数名不符合SDK要求,需将下划线命名改为驼峰命名:
// 原错误代码 const s3 = new S3({ region, access_key, secret_key }) // 修正后代码 const s3 = new S3({ region, accessKeyId: access_key, secretAccessKey: secret_key })
补充:环境变量名存在拼写错误:AWS_ACCESSS_KEY多了一个S(应为AWS_ACCESS_KEY),AWS_SCERET_KEY拼写错误(应为AWS_SECRET_KEY),这会导致凭证加载失败,必须修正环境变量名。
代码逻辑拼写错误
批量上传函数中files.lenght为拼写错误,应改为files.length,虽不直接导致访问拒绝,但会引发逻辑异常:
// 原错误代码 if(!files || files.lenght <1){ return []; } // 修正后 if(!files || files.length <1){ return []; }
AWS SDK V3 适配修正
升级V3后SDK调用方式完全变更,以下是正确的V3上传代码示例:
const { S3Client, PutObjectCommand } = require("@aws-sdk/client-s3"); require("dotenv").config(); const fs = require("fs"); const bucketName = process.env.AWS_BUCKET_NAME; const region = process.env.AWS_BUCKET_REGION; const accessKey = process.env.AWS_ACCESS_KEY; // 修正后的环境变量名 const secretKey = process.env.AWS_SECRET_KEY; // 修正后的环境变量名 // 初始化S3客户端 const s3Client = new S3Client({ region, credentials: { accessKeyId: accessKey, secretAccessKey: secretKey, }, }); async function uploadImage(file, name) { const fileContent = fs.readFileSync(file.path); const params = { Bucket: bucketName, Key: name, Body: fileContent, ACL: "public-read", ContentType: "image/jpeg", }; await s3Client.send(new PutObjectCommand(params)); // V3不会自动返回Location,需手动拼接访问地址 return { Location: `https://${bucketName}.s3.${region}.amazonaws.com/${name}` }; } async function uploadImages(files) { if (!files || files.length < 1) { return []; } return Promise.all( files.filter(file => file).map(file => uploadImage(file, file.filename)) ); } module.exports = { uploadImage, uploadImages };
2. 验证IAM权限配置
即使S3桶是公开的,上传操作仍需IAM实体(用户/EC2实例角色)拥有以下权限:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:PutObjectAcl" // 设置public-read ACL必须的权限 ], "Resource": "arn:aws:s3:::你的桶名称/*" } ] }
- 确保权限的
Resource指定为桶下所有对象(带/*后缀),而非桶本身 - 若EC2使用实例角色,需确认实例已关联该角色且权限配置正确
3. 检查S3桶公共访问设置
登录AWS控制台进入S3桶「权限」页面,确认以下选项已关闭:
- 阻止新的公共 ACL 和上传带有公共 ACL 的对象
- 忽略公共 ACL
- 阻止通过任何访问方法进行公共访问
这些设置会覆盖代码中的public-readACL配置,导致上传失败或对象无法公开访问。
4. 验证凭证有效性
- 本地环境:使用AWS CLI执行
aws s3 ls s3://你的桶名称,测试凭证是否能正常访问S3 - EC2环境:安装AWS CLI执行上述命令,确认实例能正常访问S3
内容的提问来源于stack exchange,提问作者Shivraj Thapliyal
相关产品推荐
相关产品推荐

