我和 Vultr 合作了很长时间,当我想存储一些媒体文件时,我想到了 AWS 的 S3,而 Vultr 提供了 S3 兼容的服务(对象存储)。我可以使用 s3cmd CLI 来玩服务,他们指向使用 boto3 与 S3 服务交互。我想让我的对象有签名的 URL,但我相信 boto3amazonaws.com
在代码中的某处将主机名作为常量,并且不能从配置中更改,如下所示:
import logging
from django.conf import settings
import boto3
from botocore.exceptions import ClientError
from premarket.models import PreMarket
from .models import SupervisorLogs
class Supervisor():
def __init__(self) -> None:
self.bucket_name = settings.BUCKET_NAME
self.link_expiration = settings.ONE_WEEK
self.queryset = PreMarket.objects.all()
# Generate a presigned URL for the S3 object
self.s3_configs_object = settings.AWS_S3_CREDS
self.s3_client = boto3.client('s3', **self.s3_configs_object)
def sign_objects(self):
for obj in self.queryset:
try:
presigned_url = self.create_presigned_url(obj.video_url)
obj.presigned_url = presigned_url
obj.save()
except Exception as e:
self.supervisor_logs(level="ERROR", message=e, description=e)
logging.error(e)
self.supervisor_logs(level="COMPLETE",
message="Object URL signing has completed",
description="Object URL signing has completed")
def create_presigned_url(self, object_name):
"""Generate a presigned URL to share an S3 object
:param object_name: string
:return: Presigned URL as string. If error, returns None.
"""
try:
response = self.s3_client.generate_presigned_url('get_object',
Params={
'Bucket': self.bucket_name,
'Key': object_name},
ExpiresIn=self.link_expiration)
except ClientError as e:
logging.error(e)
self.supervisor_logs(level="ERROR", message=e, description=e)
return None
# The response contains the presigned URL
return response
def supervisor_logs(self, message: str = None, level: str = None, description: str = None) -> None:
SupervisorLogs.objects.create(
message=message, level=level, description=description)
AWS S3 凭证:
AWS_S3_CREDS = {
'aws_access_key_id': AWS_ACCESS_KEY_ID,
'aws_secret_access_key': AWS_SECRET_ACCESS_KEY,
'region_name': 'ewr',
'endpoint_url': AWS_BUCKET_HOSTNAME
}
但是 Vultr 提供了不同的主机名,如下所示:
ewr1.vultrobjects.com
对象示例:
https://ewr1.vultrobjects.com/my-s3-bucket/basics/video.mp4
尝试使用我上面编写的代码对其进行签名会产生以下结果(不起作用):
https://ewr1.vultrobjects.com/my-s3-bucket/https%3A//ewr1.vultrobjects.com/my-s3-bucket/basics/video.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AccessKeyHere%2F20210706%2Fewr%2Fs3%2Faws4_request&X-Amz-Date=20210706T133319Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=bb7da3183691052ea5b25218ab1fb876fec7053a2b045957fec12cd131393a19
乍一看有几个问题:URL 是无效的,就好像它正在被连接一样,即使我出于测试目的手动删除它,它仍然无法正常工作。
Vultr 没有提供任何有关此的文件,因为他们的支持已通知我。在这一点上,我想知道我如何才能访问这些对象(没有预签名的 URL),只使用仍然无法工作的访问密钥。
我不知道我错过了什么,我希望有人对此有一些经验,因为我在过去几天找不到任何东西?
谢谢您的帮助。