Django + S3 签名过期
Django + S3 Signature expiration
我的 django-storage 实例是否应该将 S3 签名与图像名称一起存储在数据库中?
如果是这样,假设旧请求已过期,您如何为每个请求重新生成新密钥?
models.py
def user_directory_path(self, filename):
return 'profile/user_{0}/images/profile/{1}'.format(self.user.id, filename)
...
...
user_image = models.ImageField(upload_to=user_directory_path, storage=PrivateMediaStorage(), blank=True)
storage_backends.py
class PrivateMediaStorage(S3Boto3Storage):
location = 'private'
default_acl = 'private'
file_overwrite = False
custom_domain = False
抱歉 Django 新手,想确保我的逻辑是正确的。
不,您不希望它存储此类数据,因为那样您将无法访问该文件。我过去也遇到过这个问题。
签名应该是系统在需要访问文件的时候加上的。
这些是我的设置,无需保存签名即可用于私有 S3 存储桶;
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
S3_BUCKET = env('S3_BUCKET', 'my_bucket')
S3_SUB_BUCKET = env('S3_SUB_BUCKET', 'dev')
S3_REGION = env('S3_REGION', 'eu-west-2')
AWS_REGION = env('AWS_REGION', 'eu-west-2')
S3_USE_SIGV4 = True
AWS_S3_PATH_SEPARATOR = '/'
AWS_STORAGE_BUCKET_NAME = S3_BUCKET
AWS_S3_HOST = f'{S3_BUCKET}.s3.{S3_REGION}.amazonaws.com'
AWS_S3_SIGNATURE_VERSION = 's3v4'
AWS_S3_ADDRESSING_STYLE = 'virtual'
AWS_DEFAULT_ACL = 'private'
AWS_LOCATION = S3_SUB_BUCKET
AWS_S3_FILE_OVERWRITE = False
您在自定义存储中定义的一些设置 class 我在设置中保存 sub-classing。
当使用 file/image 字段时,我会这样做;
photo = models.ImageField(
verbose_name=_('photo'),
upload_to='photos',
default=None,
blank=True,
null=True,
)
在我的 upload_to
可调用的字段上,我有这些方法;
def uuid():
""" Generate a UUID """
return urlsafe_b64encode(uuid4().bytes).decode("ascii").rstrip("=")
def upload_path(instance, filename):
""" Upload to path with UUID """
return "{uuid}/{file}".format(uuid=uuid(), file=filename)
AWS_S3_ADDRESSING_STYLE
之类的文档不是很好,但这是我错过了一段时间的文档,它会导致东西存储在我的存储桶中的意外位置。我想我在没有该设置的情况下遇到了 <bucket>/<bucket>/<path_to_file
类型问题。
我的 django-storage 实例是否应该将 S3 签名与图像名称一起存储在数据库中?
如果是这样,假设旧请求已过期,您如何为每个请求重新生成新密钥?
models.py
def user_directory_path(self, filename):
return 'profile/user_{0}/images/profile/{1}'.format(self.user.id, filename)
...
...
user_image = models.ImageField(upload_to=user_directory_path, storage=PrivateMediaStorage(), blank=True)
storage_backends.py
class PrivateMediaStorage(S3Boto3Storage):
location = 'private'
default_acl = 'private'
file_overwrite = False
custom_domain = False
抱歉 Django 新手,想确保我的逻辑是正确的。
不,您不希望它存储此类数据,因为那样您将无法访问该文件。我过去也遇到过这个问题。
签名应该是系统在需要访问文件的时候加上的。
这些是我的设置,无需保存签名即可用于私有 S3 存储桶;
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
S3_BUCKET = env('S3_BUCKET', 'my_bucket')
S3_SUB_BUCKET = env('S3_SUB_BUCKET', 'dev')
S3_REGION = env('S3_REGION', 'eu-west-2')
AWS_REGION = env('AWS_REGION', 'eu-west-2')
S3_USE_SIGV4 = True
AWS_S3_PATH_SEPARATOR = '/'
AWS_STORAGE_BUCKET_NAME = S3_BUCKET
AWS_S3_HOST = f'{S3_BUCKET}.s3.{S3_REGION}.amazonaws.com'
AWS_S3_SIGNATURE_VERSION = 's3v4'
AWS_S3_ADDRESSING_STYLE = 'virtual'
AWS_DEFAULT_ACL = 'private'
AWS_LOCATION = S3_SUB_BUCKET
AWS_S3_FILE_OVERWRITE = False
您在自定义存储中定义的一些设置 class 我在设置中保存 sub-classing。
当使用 file/image 字段时,我会这样做;
photo = models.ImageField(
verbose_name=_('photo'),
upload_to='photos',
default=None,
blank=True,
null=True,
)
在我的 upload_to
可调用的字段上,我有这些方法;
def uuid():
""" Generate a UUID """
return urlsafe_b64encode(uuid4().bytes).decode("ascii").rstrip("=")
def upload_path(instance, filename):
""" Upload to path with UUID """
return "{uuid}/{file}".format(uuid=uuid(), file=filename)
AWS_S3_ADDRESSING_STYLE
之类的文档不是很好,但这是我错过了一段时间的文档,它会导致东西存储在我的存储桶中的意外位置。我想我在没有该设置的情况下遇到了 <bucket>/<bucket>/<path_to_file
类型问题。