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

添加自定义域名后DigitalOcean私有文件访问被拒,能否用自定义域名访问?

解决方案:Django私有文件通过DigitalOcean自定义域名访问

问题原因

当设置custom_domain=True时,S3Boto3Storage会生成不带签名的直接URL(//media.mydomain.com/private/xxx),但私有文件的ACL是private,DigitalOcean Spaces要求必须通过带签名的URL才能访问,因此触发AccessDenied错误。而custom_domain=False时生成的是带签名的DO官方域名URL,所以能正常访问,但不符合自定义域名需求。

解决步骤

1. 确认自定义域名配置正确

  • 在DigitalOcean控制台完成Spaces与media.mydomain.com的绑定:添加CNAME记录指向你的Spaces域名(例如sfo3.digitaloceanspaces.com)
  • 配置并启用自定义域名的SSL证书(DigitalOcean提供免费自动续约证书)

2. 修改私有存储类代码

重写url方法,让它生成带签名的自定义域名URL:

from storages.backends.s3boto3 import S3Boto3Storage

class PrivateMediaStorage(S3Boto3Storage):
    location = 'private'
    default_acl = 'private'
    file_overwrite = False
    custom_domain = False  # 保持默认,由我们手动替换域名

    def url(self, name, parameters=None, expire=None, http_method=None):
        # 调用父类方法生成带签名的DO域名URL
        signed_url = super().url(name, parameters, expire, http_method)
        # 替换DO域名为自定义域名
        do_bucket_domain = f"{self.bucket_name}.sfo3.digitaloceanspaces.com"  # 替换为你的Spaces完整域名
        custom_domain = "media.mydomain.com"  # 替换为你的自定义域名
        return signed_url.replace(do_bucket_domain, custom_domain)

3. 验证效果

  • 重启Django服务
  • 在模板中调用{{ media.url }},生成的URL会是https://media.mydomain.com/private/xxx?X-Amz-Algorithm=...格式(带有签名参数)
  • 点击该URL,私有文件即可正常访问,不再出现AccessDenied错误

额外说明

  • 预签名URL默认有效期为1小时,可通过expire参数调整(单位:秒)
  • 普通公开媒体文件可单独配置另一个存储类,设置custom_domain=True直接使用自定义域名访问(无需签名)

内容的提问来源于stack exchange,提问作者sdg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:45:37