Heroku应用访问AWS S3存储桶图片返回403 Forbidden错误如何解决
403错误排查方向
- 1. 未配置存储桶公共读策略
关闭「Block all public access」只是解除了公开访问的限制,不会自动给匿名用户赋予读取权限。你需要在S3存储桶的「权限」-「桶策略」中添加如下配置,替换your-bucket-name为实际桶名:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::your-bucket-name/*" } ] }
- 2. 缺少默认公开ACL配置
默认情况下上传到S3的文件ACL为私有,即使桶公开也无法匿名访问。在你的Django配置中添加如下参数:
AWS_DEFAULT_ACL = 'public-read'
- 3. 区域配置不匹配
你的配置中没有显式指定S3区域,django-storages默认会使用us-east-1,和你MEDIA_URL中的eu-west-1不一致会触发403。添加如下配置:
AWS_S3_REGION_NAME = 'eu-west-1' AWS_S3_ADDRESSING_STYLE = 'virtual'
- 4. 访问协议错误
2023年之后新建的S3桶默认强制HTTPS访问,你配置的MEDIA_URL用了HTTP协议,会被S3拦截。修改为HTTPS:
MEDIA_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.eu-west-1.amazonaws.com/'
- 5. IAM用户权限不足
检查你Access Key对应的IAM用户,是否附加了允许S3读写的权限策略,最小权限示例如下,替换your-bucket-name为实际桶名:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:GetObject", "s3:DeleteObject" ], "Resource": "arn:aws:s3:::your-bucket-name/*" } ] }
- 6. 环境变量配置错误
注意你代码中os.environ.get()的参数是Heroku后台配置的环境变量键名,不是直接填你的密钥明文。比如你在Heroku Config Vars里设置的键是AWS_ACCESS_KEY_ID,代码就应该写os.environ.get('AWS_ACCESS_KEY_ID'),如果键名不匹配会导致认证失败返回403。 - 7. 文件存储后端配置缺失
你当前配置中注释掉了DEFAULT_FILE_STORAGE,如果没有自定义单独处理媒体文件上传到S3的逻辑,用户上传的文件会默认存在Heroku本地磁盘,Heroku的文件系统是临时的,重启后文件就会消失,此时访问S3对应路径自然会返回403。确认你要么取消该行注释,要么自己实现了媒体文件上传到S3的逻辑。
内容的提问来源于stack exchange,提问作者VaultDweller
相关产品推荐
相关产品推荐

