Django应用从AWS S3获取静态文件时出现403禁止访问错误
Django + AWS S3 静态文件403禁止访问问题解决
背景
已在AWS上完成Django Web应用的开发与部署,使用RDS Postgres作为数据库。部署阶段通过collectstatic命令收集静态文件,该环节问题已解决。
问题现象
collectstatic执行成功且静态文件已上传至S3存储桶,但前端HTML加载静态文件时持续返回403错误:
GET https://postgram-bucket.s3.amazonaws.com/static/css/main.css net::ERR_ABORTED 403 (Forbidden) GET https://postgram-bucket.s3.amazonaws.com/static/css/bootstrap.min.css net::ERR_ABORTED 403 GET https://postgram-bucket.s3.amazonaws.com/static/img/postgram_logo.png 403 (Forbidden)
已完成排查
- 确认
collectstatic执行成功,静态文件已正确上传至S3存储桶 - 验证Django应用关联的IAM角色已配置S3存储桶必要操作权限
- 通过Postman携带凭证可正常获取目标静态文件
关键配置(settings.py)
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ os.path.join(BASE_DIR, 'templates') ], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] ########## # AWS S3 # ########## USE_S3 = env('USE_S3') == 'TRUE' if USE_S3: # AWS settings AWS_S3_VERITY = True AWS_DEFAULT_ACL = None AWS_S3_FILE_OVERWRITE = False AWS_S3_SIGNATURE_NAME = 's3v4' AWS_ACCESS_KEY_ID = env('AWS_ACCESS_KEY_ID') AWS_SECRET_ACCESS_KEY = env('AWS_SECRET_ACCESS_KEY') AWS_STORAGE_BUCKET_NAME = env('AWS_STORAGE_BUCKET_NAME') AWS_S3_REGION_NAME = env('AWS_S3_REGION_NAME') AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com' AWS_S3_OBJECT_PARAMETERS = {'CacheControl': 'max-age=86400'} # S3 static settings AWS_LOCATION = 'static' STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{AWS_LOCATION}/' STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' else: STATIC_URL = '/staticfiles/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),) MEDIA_URL = '/mediafiles/' MEDIA_ROOT = os.path.join(BASE_DIR, 'mediafiles')
解决方法
更新S3存储桶的桶策略,添加允许公共读取对象的权限即可解决问题。策略内容如下(需将bucket-name替换为你的实际存储桶名称):
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::bucket-name/*" ] } ] }
内容的提问来源于stack exchange,提问作者xavier
相关产品推荐
相关产品推荐

