Непоследовательное поведение в методе boto3 generate_presigned_url (), иногда SignatureDoesNotMatch - PullRequest
0 голосов
/ 27 июня 2019

В настоящее время я нахожусь в довольно напряженном состоянии и не знаю, как поступить.

В настоящее время я создаю платформу обмена сообщениями с полным стеком, где пользователи могут отправлять друг другу сообщения с вложениями. Это очень похоже на урезанную почтовую систему.

Я хочу, чтобы загруженные пользователем файлы размещались на S3. Эта корзина S3 будет (в конце концов) иметь список контроля доступа, но в настоящее время она общедоступна. В результате я пытаюсь осуществить загрузку вложений по заранее заданному URL-адресу, который я отображаю на стороне клиента. Пользователь щелкает URL-адрес, попадает в AWS, и загрузка файла начинается автоматически. По крайней мере, это должно быть поведение.

Когда я загружаю файлы (я делаю это в пакетах по 4 файла, все разные типы файлов), я печатаю предварительно сгенерированные URL-адреса, которые я генерирую, со сроком действия по умолчанию 1 час.

Дело в том, что обычно эти URL работают! Я нажимаю на них, и файл загружается. Однако время от времени я получаю ошибку SignatureDoesNotMatch, редко для всех 4 файлов в пакете, но, возможно, один или два. Похоже, что все остальные сообщения в SO, связанные с этой ошибкой, вызваны неправильной вставкой учетных данных AWS Access, поэтому я обязательно проверил их. Я не уверен, в чем проблема, и хотел бы увидеть, если бы кто-то еще имел эту проблему.

Вот код для моих методов:

class AttachmentTest(APIView):
    '''
    POST:
    Creates an Attachment Model per attachment sent
    '''

    def post(self, request):
        print(request.FILES)
        s3 = boto3.resource('s3')
        folder_name = str(uuid.uuid4())
        for file in request.FILES:
            object_key = 'mail_attachments/' + request.user.username + '/' + folder_name + '/' + request.FILES[file].name
            s3.Bucket('MY_BUCKET_NAME').put_object(Key=object_key, Body=request.FILES[file], ContentType=request.FILES[file].content_type)
            print(create_presigned_url('MY_BUCKET_NAME', object_key))
        return Response("attachment logged")

Выше находится конечная точка API, в которую я отправляю файлы через Почтальона.

Вот метод create_presigned_url(), скопированный прямо из документации AWS:

def create_presigned_url(bucket_name, object_name, expiration=3600):
    """Generate a presigned URL to share an S3 object

    :param bucket_name: string
    :param object_name: string
    :param expiration: Time in seconds for the presigned URL to remain valid
    :return: Presigned URL as string. If error, returns None.
    """

    # Generate a presigned URL for the S3 object
    s3_client = boto3.client('s3')
    try:
        response = s3_client.generate_presigned_url('get_object',
                                                    Params={'Bucket': bucket_name,
                                                            'Key': object_name},
                                                    ExpiresIn=expiration)
    except ClientError as e:
        logging.error(e)
        return None

    # The response contains the presigned URL
    return response

Вот примерный URL: https://<MY_BUCKET_NAME>.s3.amazonaws.com/mail_attachments/isaac/775054eb-a83e-49e1-974d-bbf3f88e32ba/%F0%9F%98%80?AWSAccessKeyId=<MY_ACCESS_KEY>&Signature=SFodxvdJbVvClINL7M%2BZPym273Y%3D&Expires=1561585952

Пожалуйста, дайте мне знать, если вы столкнулись с этой проблемой. Я не уверен, является ли это ошибкой на стороне Amazon (я предполагаю, что вероятность возникновения ошибки в 100 раз выше, чем у команды AWS, хаха.) У меня есть идея, что это может быть связано с тем, как URL закодирован, но я не совсем уверен. Спасибо за помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...