无法删除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
相关产品推荐
相关产品推荐

