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

DigitalOcean Spaces中Django存储签名不匹配及URL优化求助

解决Django + DigitalOcean Spaces 生成带签名URL的问题

问题原因

  1. 未适配DigitalOcean Spaces要求的S3签名版本和区域,导致签名计算不匹配
  2. django-storages默认会生成带签名的URL,即使文件已设置public-read权限
  3. AWS_S3_ENDPOINT_URL末尾带斜杠,可能引发URL拼接异常

修复步骤

1. 修正settings.py配置

补充并调整关键配置项:

AWS_ACCESS_KEY_ID = 'DO009ABCDEFGH'
AWS_SECRET_ACCESS_KEY = 'Nsecret_key'
AWS_STORAGE_BUCKET_NAME = 'bucket_name'
AWS_DEFAULT_ACL = 'public-read'
# 去掉末尾斜杠,避免URL拼接错误
AWS_S3_ENDPOINT_URL = 'https://transcribe-spaces.nyc3.digitaloceanspaces.com'
# 适配DigitalOcean Spaces的签名规则
AWS_S3_SIGNATURE_VERSION = 's3v4'
AWS_S3_REGION_NAME = 'nyc3'
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400'
}

AWS_MEDIA_LOCATION = 'media/'
PUBLIC_MEDIA_LOCATION = 'media/'
MEDIA_URL = f"{AWS_S3_ENDPOINT_URL}/{AWS_MEDIA_LOCATION}"
DEFAULT_FILE_STORAGE = 'mysite.storage_backends.MediaStorage'

2. 修改存储后端类(mysite/storage_backends.py)

重写url方法,直接返回无签名的公共URL:

from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage

class MediaStorage(S3Boto3Storage):
    location = settings.AWS_MEDIA_LOCATION
    default_acl = settings.AWS_DEFAULT_ACL

    def url(self, name, parameters=None, expire=None):
        # 跳过签名逻辑,直接构造公共访问路径
        return f"{settings.AWS_S3_ENDPOINT_URL}/{settings.AWS_STORAGE_BUCKET_NAME}/{self.location}{name}"

3. 验证修复效果

  • 重新上传文件,检查数据库中保存的URL是否为纯路径格式(如https://my-spaces.nyc3.digitaloceanspaces.com/media/uploads/Recording_2.mp3)
  • 直接访问该URL,确认文件能正常打开
  • 使用requests调用该URL,检查返回状态码是否为200

额外处理

如果数据库中已有带签名的旧URL,需批量更新记录,去掉?AWSAccessKeyId=...及后续参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:25:23