Предварительно подписанные URL-адреса в Vultr Object Storage с использованием boto3
Я работаю с Vultr довольно долгое время, и когда я хотел сохранить некоторые мультимедийные файлы, я подумал об AWS S3, а Vultr предоставляет совместимый с S3 сервис (Object Storage). Я могу использовать s3cmd CLI для игры со службой, и они указывают на использование boto3 для взаимодействия со службой S3. Я хотел, чтобы у моих объектов были подписанные URL-адреса, но я считаю, что у boto3 есть
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-адресов), с помощью только ключа доступа, который все равно не будет работать.
Я не знаю, что мне не хватает, и я надеюсь, что у кого-то есть опыт с этим раньше, поскольку я не мог ничего найти в последние пару дней?
Спасибо за помощь.
1 ответ
В приведенном выше коде вы используете URL-адрес:
presigned_url = self.create_presigned_url(obj.video_url)
Вы пытались использовать местоположение s3 для создания URL-адреса? Судя по всему, obj.video_url - это https: // ewr1 ...... где, поскольку URL-адрес s3 будет s3: // и может быть лучше использован библиотекой, которую вы используете.
Кроме того, прежде чем выполнять весь цикл для каждого URL-адреса, я бы попробовал что-нибудь ручное, например:
presigned_url = self.create_presigned_url('s3://ewr1.vultrobjects.com/my-s3-bucket/basics/video.mp4')
Посмотрим, доставит ли это вам какое-нибудь удовольствие