You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法删除AWS S3存储桶内文件的问题排查求助

S3删除文件提示Access Denied问题排查与解决

我开发了一个允许用户发布含文件内容帖子的Web应用,文件托管在AWS S3存储桶中(采用Node.js + Express技术栈)。用户可以成功上传和获取文件,但删除文件时会收到“Access Denied”(访问被拒绝)的响应。

存储桶权限配置

尽管创建S3存储桶时,我已配置允许Put、Get和Delete权限,访问策略的JSON内容如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::saud-demo-bucket/*"
        }
    ]
}

应用代码片段

为验证Node.js应用中的凭据和传入数据是否正确,我在getFileFromS3()和deleteFileFromS3()函数中添加了console.log()语句:

从S3存储桶获取文件

async function getFileFromS3(req) {

  console.log("REQ.QUERY.S3FILENAME IN GET FUNCTION IS:");
  console.log(req.query.s3FileName);

  const params = {
    Bucket: bucketName,
    Key: req.query.s3FileName,
  };

  const command = new GetObjectCommand(params);
  const file = await s3.send(command);

  if (file.$metadata.httpStatusCode === 200) {
    console.log("File retreived successfully!");
    return {
      success: true,
      file,
    };
  } else {
    console.log("Error retreiving file ..");
    return {
      err: true,
      file,
    };
  }
}

从S3存储桶删除文件

async function deleteFileFromS3(req) {
  console.log("REQ.QUERY.S3FILENAME IN DELETE FUNCTION IS:");
  console.log(req.query.s3FileName);

  const params = {
    Bucket: bucketName,
    Key: req.query.s3FileName,
  };

  const command = new DeleteObjectCommand(params);
  const result = await s3.send(command);

  if (result.$metadata.httpStatusCode === 200) {
    console.log("File deleted successfully!");
    return true;
  } else {
    console.log("Error deleting file ..");
    return false;
  }
}

终端输出

[nodemon] starting `node server/server.js`
Listening ...
Connected to database successfully!
REQ.QUERY.S3FILENAME IN GET FUNCTION IS:
5e55c3065c73e828dfe2a5e1c1cf777f8ad9235b8cf3dbbcf6572f03979b32cb.docx
File retreived successfully!
REQ.QUERY.S3FILENAME IN DELETE FUNCTION IS:
5e55c3065c73e828dfe2a5e1c1cf777f8ad9235b8cf3dbbcf6572f03979b32cb.docx
(node:15800) UnhandledPromiseRejectionWarning: AccessDenied: Access Denied
    at throwDefaultError (C:\Users\user\Desktop\Folders\Dev\Web\Projects\seu-students\node_modules\@aws-sdk\smithy-client\dist-cjs\default-error-handler.js:8:22)       

排查与解决步骤

  • 检查IAM凭据权限:存储桶策略是资源级授权,但应用使用的IAM用户/角色必须自身拥有s3:DeleteObject权限。打开IAM控制台,找到应用使用的凭据对应的身份,查看其附加的策略,确认包含允许s3:DeleteObject操作且资源匹配的语句。
  • 检查版本控制状态:如果存储桶开启了版本控制,DeleteObject操作只会添加一个删除标记,不会真正删除对象。若要彻底删除,需要使用DeleteObjectVersion权限,并在请求中指定版本ID;或者临时关闭版本控制后再执行删除。
  • 确认对象所有权:如果文件是由其他AWS账户上传的,当前账户即使有桶策略允许,也可能无法删除该对象。可以在S3控制台查看对象的“所有者”信息,若不属于当前账户,需要联系上传账户赋予删除权限,或者通过桶策略配置对象所有权控制。
  • 验证Key的精确匹配:S3对象的Key区分大小写,且对隐形字符(如空格、换行符)敏感。确认删除请求中的Key与存储的对象Key完全一致,可通过S3控制台查看对象的完整Key进行对比。
  • 排查Deny类策略:检查是否存在组织级SCP(服务控制策略)、IAM中的Deny语句或桶策略中的Deny规则,这些会优先于Allow权限导致访问被拒绝。
  • 优化错误捕获:修改deleteFileFromS3函数,添加try/catch块捕获异常,获取更详细的错误信息,帮助定位问题:
    async function deleteFileFromS3(req) {
      console.log("REQ.QUERY.S3FILENAME IN DELETE FUNCTION IS:");
      console.log(req.query.s3FileName);
    
      const params = {
        Bucket: bucketName,
        Key: req.query.s3FileName,
      };
    
      try {
        const command = new DeleteObjectCommand(params);
        const result = await s3.send(command);
        if (result.$metadata.httpStatusCode === 200) {
          console.log("File deleted successfully!");
          return true;
        }
      } catch (err) {
        console.error("Delete error details:", err);
        return false;
      }
    }
    

内容的提问来源于stack exchange,提问作者Saud Alghamdi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 17:18:03