Django连接AWS触发403 Forbidden错误,寻求排查方案
Django项目连接AWS S3执行collectstatic报403 Forbidden错误
问题描述
从Git克隆了一个此前可正常运行的Django项目,尝试连接AWS时执行collectstatic命令触发403错误,错误栈如下:
Traceback (most recent call last): File "manage.py", line 21, in <module> main() File "manage.py", line 17, in main execute_from_command_line(sys.argv) File "C:\Users\cuens\PycharmProjects\frozen-brushlands-41873\venv\lib\site-packages\django\core\management\__init__.py", line 401, in execute_from_command_line utility.execute() File "C:\Users\cuens\PycharmProjects\frozen-brushlands-41873\venv\lib\site-packages\django\core\management\__init__.py", line 395, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "C:\Users\cuens\PycharmProjects\frozen-brushlands-41873\venv\lib\site-packages\django\core\management\base.py", line 328, in run_from_argv self.execute(*args, **cmd_options) File "C:\Users\cuens\PycharmProjects\frozen-brushlands-41873\venv\lib\site-packages\django\core\management\base.py", line 369, in execute output = self.handle(*args, **options) File "C:\Users\cuens\PycharmProjects\frozen-brushlands-41873\venv\lib\site-packages\django\contrib\staticfiles\management\commands\collectstatic.py", line 187, in handle collected = self.collect() File "C:\Users\cuens\PycharmProjects\frozen-brushlands-41873\venv\lib\site-packages\django\contrib\staticfiles\management\commands\collectstatic.py", line 113, in collect handler(path, prefixed_path, storage) File "C:\Users\cuens\PycharmProjects\frozen-brushlands-41873\venv\lib\site-packages\django\contrib\staticfiles\management\commands\collectstatic.py", line 338, in copy_file if not self.delete_file(path, prefixed_path, source_storage): File "C:\Users\cuens\PycharmProjects\frozen-brushlands-41873\venv\lib\site-packages\django\contrib\staticfiles\management\commands\collectstatic.py", line 248, in delete_file if self.storage.exists(prefixed_path): File "C:\Users\cuens\PycharmProjects\frozen-brushlands-41873\venv\lib\site-packages\storages\backends\s3boto3.py", line 469, in exists self.connection.meta.client.head_object(Bucket=self.bucket_name, Key=name) File "C:\Users\cuens\PycharmProjects\frozen-brushlands-41873\venv\lib\site-packages\botocore\client.py", line 401, in _api_call return self._make_api_call(operation_name, kwargs) File "C:\Users\cuens\PycharmProjects\frozen-brushlands-41873\venv\lib\site-packages\botocore\client.py", line 731, in _make_api_call raise error_class(parsed_response, operation_name) botocore.exceptions.ClientError: An error occurred (403) when calling the HeadObject operation: Forbidden
项目中的AWS配置:
AWS_S3_ACCESS_KEY_ID = os.environ.get('AWS_S3_ACCESS_KEY_ID') AWS_s3_SECRET_ACCESS_KEY = os.environ.get('AWS_S3_SECRET_ACCESS_KEY') AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME') AWS_S3_HOST = 's3.us-east-2.amazonaws.com' AWS_S3_REGION_NAME = 'us-east-2' AWS_S3_CUSTOM_DOMAIN = '%s.%s' % (AWS_STORAGE_BUCKET_NAME, AWS_S3_HOST) AWS_DEFAULT_ACL = None AWS_LOCATION = 'static' STATICFILES_DIRS = [ os.path.join(BASE_DIR, "static"), ] STATIC_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION) PUBLIC_MEDIA_LOCATION = 'media' MEDIA_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, PUBLIC_MEDIA_LOCATION) DEFAULT_FILE_STORAGE = 'blog.storage_backends.MediaStorage' DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' STATICFILES_STORAGE = 'storages.backends.s3boto3.S3StaticStorage'
S3桶权限配置:
{ "Version": "2008-10-17", "Statement": [ { "Sid": "AllowPublicRead", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::wickedphoto-blog/*" } ] }
项目克隆前可正常运行,目前无法定位问题,需要排查。
排查与解决步骤
1. 修正环境变量键名大小写问题
配置中AWS_s3_SECRET_ACCESS_KEY的s3是小写,而标准环境变量键应为全大写的AWS_S3_SECRET_ACCESS_KEY,这会导致无法正确读取密钥,直接引发权限错误。修改为:
AWS_S3_SECRET_ACCESS_KEY = os.environ.get('AWS_S3_SECRET_ACCESS_KEY')
2. 补充IAM用户必要权限
当前S3桶策略仅允许公共读取GetObject,但collectstatic需要写入、列出、检查对象存在的权限。给对应IAM用户添加以下策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:ListBucket", "s3:HeadObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::wickedphoto-blog", "arn:aws:s3:::wickedphoto-blog/*" ] } ] }
3. 修复存储配置覆盖问题
配置中两次设置DEFAULT_FILE_STORAGE,最后一行会覆盖自定义的MediaStorage。如果原项目依赖自定义存储后端处理媒体文件,需保留第一行;否则删除重复配置,确保逻辑一致。
4. 验证桶名与区域匹配
确认AWS_STORAGE_BUCKET_NAME环境变量值为wickedphoto-blog,且桶确实创建在us-east-2区域,区域不匹配会导致签名错误触发403。
5. 直接测试凭证有效性
用AWS CLI测试凭证能否访问桶:
aws s3 ls s3://wickedphoto-blog --region us-east-2
若返回403,说明凭证本身无权限;若能列出内容,再检查Django配置是否正确读取环境变量。
内容的提问来源于stack exchange,提问作者Wickedly Gaming
相关产品推荐
相关产品推荐

