Ошибка SignatureDoesNotMatch при создании предварительно назначенного URL-адреса для загрузки изображения boto3, React - PullRequest
0 голосов
/ 15 марта 2020

Я уже некоторое время отлаживаю эту ошибку, и ни одно из найденных мной решений не помогло. В настоящее время мое приложение отправляет запрос от React на мой Django Rest API, чтобы получить предварительно назначенный URL для загрузки изображений. Код для получения предварительно заданного URL-адреса приведен здесь:

bucket_name = json_data["aws_photo_bucket_name"]
access_key_id = json_data["aws_photo_bucket_id"]
secret_access_key = json_data["aws_photo_bucket_secret_key"]

# Get the service client.
s3 = boto3.client(
    's3',
    config=Config(signature_version='s3v4'),
    aws_access_key_id=access_key_id,
    aws_secret_access_key=secret_access_key)

# create a unique file name for upload
custom_key = "PostImages/" + str(user_id) + "-" + str(time.time()) + "-" + str(file_name)

# Generate the URL for uploading 'key' to 'Bucket'
url = s3.generate_presigned_url(
    ClientMethod='put_object',
    Params={
        'ACL': 'public-read',
        'Bucket': bucket_name,
        'ContentType': file_type,
        'Expires': 10000,
        'Key': custom_key
    }
)

Я знаю, что мои учетные данные верны, поскольку приведенный выше код работает для ClientMethod "get_object", но по какой-то причине я не могу загрузить его через "put_object" ClientMethod. Когда я получаю доступ к URL-адресу, сгенерированному выше, через браузер, я получаю:

<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your key and signing method.
</Message>

Когда я пытаюсь POST к URL-адресу из React, используя следующий код, я получаю ошибку 403, которая, как я полагаю, связана с Ошибка SignatureDoesNotMatch.

getPresignedURL = (file) => {
    let fileType = file.type;
    let fileName = file.name;

    let postData = {"file_name": fileName, "file_type": fileType}

    fetch(`${config.url}/get_presigned_url/`,{
        headers: new Headers({
            'Authorization': 'Bearer  ' + getSession().jwt, 
            'Content-type': 'application/json'
        }), 
        method: 'post',
        body: JSON.stringify(postData),
    })
    .then(res => res.json())
    .then((res) => {
        console.log(res.URL)
        if (res.Success) {
            let signedURL = res.URL;
            console.log(signedURL)
            fetch(signedURL,{
                headers: new Headers({
                    'Content-type': fileType
                }), 
                method: 'POST',
                body: file
            })
            .then(res => res.json())
            .then((res) => {
                console.log(res)
            })
        }
        else {
            console.log("failed")
        }
    })
}

Я попытался получить новые учетные данные, не указав тип содержимого, установив тип содержимого "image / jpeg" (для загрузки тестового изображения) и не указав ACL

Любая помощь очень ценится!

...