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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 22:31:18