使用AWS Access Key访问S3遇AccessDenied问题及认证方式咨询
问题
我已按照AWS官方文档要求创建了AWS Access Key和Secret Key,使用以下基于@aws-sdk/client-s3的Node.js代码尝试获取指定S3桶数据时,出现了AccessDenied错误:
import { S3Client, ListObjectsCommand } from '@aws-sdk/client-s3'; export class AWS_S3Service { client: S3Client; constructor(accessKeyId: string, secretAccessKey: string) { this.client = new S3Client({ credentials: { accessKeyId, secretAccessKey, }, region: 'us-east-1', }); } async getAllDataInBucket(bucketName: string): Promise<any> { try { const command = new ListObjectsCommand({ Bucket: bucketName, }); const response = await this.client.send(command); const objects = response.Contents; if (!objects || objects.length === 0) { return []; } // Extract the keys (object names) from the objects list const keys = objects.map((object) => object.Key); return keys; } catch (error) { console.error('Error fetching data from S3:', error); throw error; } } } const accessKey = 'AK*****************5W'; const secretKey = 'qNx******************************Br'; (async () => { const newClient = new AWS_S3Service(accessKey, secretKey); const data = await newClient.getAllDataInBucket("my-testing-bucket") console.log(data); })();
请问我哪里操作有误?同时想咨询:
- 当前使用永久Access Key的方式是否正确?
- 是否必须通过Cognito用户登录获取临时Access Key和Secret Key才能访问S3桶?我不想创建Identity Pool或Cognito用户,若这是唯一方式请告知。
解决方案与说明
一、AccessDenied错误的常见原因
- IAM用户权限不足:你创建Access Key对应的IAM用户没有被授予
s3:ListBucket权限。需要给该用户附加以下类似的IAM策略(替换my-testing-bucket为你的桶名):{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::my-testing-bucket" } ] } - 桶策略限制:如果目标S3桶配置了桶策略,可能明确拒绝了该IAM用户的访问请求。检查桶策略,确保没有阻止该用户执行
s3:ListBucket操作的规则。 - 区域不匹配:代码中指定的区域是
us-east-1,但如果你的S3桶创建在其他区域,会导致权限验证失败。确认桶的实际区域,修改代码中的region参数。 - 密钥错误:检查Access Key和Secret Key是否输入正确,避免复制时包含多余空格或字符。
二、永久Access Key的使用是否正确
使用永久Access Key本身是合法的,但分场景:
- 如果是后端服务使用,只要做好密钥的安全存储(比如用环境变量、AWS Secrets Manager托管,不要硬编码在代码中),这种方式是可行的。
- 如果是前端代码(比如浏览器端)使用,绝对不推荐——永久密钥容易被泄露,导致你的AWS资源被恶意使用。
三、是否必须使用Cognito临时密钥?
不是必须的,你有其他替代方案:
- 后端代理模式:前端不直接调用S3 API,而是请求你的后端服务,由后端用自己的AWS凭证(永久密钥或IAM角色)访问S3,再把数据返回给前端。
- S3预签名URL:后端生成具有有效期的预签名URL,前端使用该URL直接访问S3对象,无需持有AWS密钥。这种方式适合让前端下载/上传特定对象,且能控制URL的有效期和权限。
- AWS服务IAM角色:如果你的代码运行在AWS服务上(比如EC2、Lambda、ECS),可以给这些服务附加IAM角色,AWS会自动为代码提供临时凭证,无需手动配置密钥,安全性更高。
内容的提问来源于stack exchange,提问作者AliOz
相关产品推荐
相关产品推荐

