Загрузка в S3 Bucket с предопределенным URL дает 403 запрещенную ошибку - PullRequest
0 голосов
/ 29 января 2020

Я пытаюсь реализовать функцию загрузки изображений для приложения Vue, используя AWS S3 предварительно подписанный URL-адрес. Первым шагом является отправка запроса в API, который создаст подписанный URL для загрузки файла. Эта часть работает нормально:

Сторона сервера:

'use strict';

const aws = require('aws-sdk');
const config = require('../config');
const util = require('./util');
const uuidv4 = require('uuid/v4');

const bucketName = 'myAmazonS3Bucket';

aws.config.update({
  secretAccessKey: config.AWS_SECRET_ACCESS_KEY,
  accessKeyId: config.AWS_ACCESS_KEY_ID,
  region: 'us-west-2'
});

const s3 = new aws.S3({ signatureVersion: 'v4' });

const handler = async (event) => {
    console.log('Uploading file...');

    return await getUploadURL();
}

const getUploadURL = async () => {
    const actionId = uuidv4();

    const s3Params = {
      Bucket: bucketName,
      Key:  `${actionId}.jpg`,
      ContentType: 'image/jpeg',
      ACL: 'public-read'
    };

    console.log(s3Params);

    return new Promise((resolve, reject) => {
        let uploadURL = s3.getSignedUrl('putObject', s3Params);

        console.log(uploadURL);

        resolve({
            "statusCode": 200,
            "isBase64Encoded": false,
            "headers": { "Access-Control-Allow-Origin": "*" },
            "body": JSON.stringify({
                "uploadURL": uploadURL,
                "photoFilename": `${actionId}.jpg`
            })
        });

        reject({
            "statusCode": 500,
            "headers": { "Access-Control-Allow-Origin": "*" },
            "body": "A funky error occurred and I am not happy about it!"
        })
    });
}

module.exports = {
    handler
}

Конечная точка API отправляет ответ, подобный этому:

{
    "uploadURL": "https://s3.us-west-2.amazonaws.com/pics.amazon-clone.io/7925d452-cadd-4f06-ba63-cc50645e3cfb.jpg?AWSAccessKeyId=AKIASGDJJ5ZLUVPMUYMQ&Content-Type=image%2Fjpeg&Expires=1580276753&Signature=3rqNckP4DiL6DkWPRuEGJsuIGpw%3D&x-amz-acl=public-read",
    "photoFilename": "7925d452-cadd-4f06-ba63-cc50645e3cfb.jpg"
}

Клиент будет использовать uploadUrl для загрузить файл в корзину S3. Вот код клиента для этого:

uploadImage: async function (e) {
            console.log('Upload clicked')
            console.log(e)

            // Get the presigned URL
            const response = await axios({
                method: 'POST',
                url: API_ENDPOINT
            })
            console.log('Response: ', response.data)
            console.log('Uploading: ', this.image)

            let binary = atob(this.image.split(',')[1])
            let array = []
            for (var i = 0; i < binary.length; i++) {
                array.push(binary.charCodeAt(i))
            }
            let blobData = new Blob([new Uint8Array(array)], {type: 'image/jpeg'})
            console.log('Uploading to: ', response.data.uploadURL)
            const result = await fetch(response.data.uploadURL, {
                method: 'PUT',
                headers: { 
                    'Content-Type': 'image/jpeg', 
                    'x-amz-acl': 'public-read' },
                body: blobData
            })
            console.log('Result: ', result)
            // Final URL for the user doesn't need the query string params
            this.uploadURL = response.data.uploadURL.split('?')[0]
        }

К сожалению, я получаю запрещенную ошибку 403 при использовании подписанного URL. Вот результат ошибок консоли, которые я получаю из моего Chrome браузера:

Загрузка в: https://s3.us-west-2.amazonaws.com/pics.amazon-clone.io/b1bdb5e3-7f64-49f7-b779-11b3f67317ee.jpg?Content-Type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIASGDJJ5ZLUVPMUYMQ%2F20200129%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20200129T165522Z&X-Amz-Expires=900&X-Amz-Signature=b230c9a40065585307e150655466bbab3d0d99aa43f8620377ab977eb1c7234c&X-Amz-SignedHeaders=host%3Bx-amz-acl&x-amz-acl=public-read

Pi c. vue? 937b: 60 ВАРИАНТОВ https://s3.us-west-2.amazonaws.com/pics.amazon-clone.io/b1bdb5e3-7f64-49f7-b779-11b3f67317ee.jpg?Content-Type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIASGDJJ5ZLUVPMUYMQ%2F20200129%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20200129T165522Z&X-Amz-Expires=900&X-Amz-Signature=b230c9a40065585307e150655466bbab3d0d99aa43f8620377ab977eb1c7234c&X-Amz-SignedHeaders=host%3Bx-amz-acl&x-amz-acl=public-read 403 (Запрещено)

Доступ к выборке в 'https://s3.us-west-2.amazonaws.com/pics.amazon-clone.io/b1bdb5e3-7f64-49f7-b779-11b3f67317ee.jpg?Content-Type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIASGDJJ5ZLUVPMUYMQ%2F20200129%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20200129T165522Z&X-Amz-Expires=900&X-Amz-Signature=b230c9a40065585307e150655466bbab3d0d99aa43f8620377ab977eb1c7234c&X-Amz-SignedHeaders=host%3Bx-amz-acl&x-amz-acl=public-read' из источника 'http://localhost : 8080 'было заблокировано политикой CORS: Ответ на запрос предварительной проверки не проходит проверку контроля доступа: в запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin». Если непрозрачный ответ отвечает вашим потребностям, установите режим запроса «no-cors», чтобы получить ресурс с отключенным CORS.

Ответы [ 2 ]

0 голосов
/ 30 января 2020

вот как я бы решил проблему. Сначала я подтвердил бы, что сгенерированный URL работает с использованием некоторых инструментов, таких как curl или postman, затем я проверил бы запрос, отправленный на s3, и нашел бы дополнительные заголовки, присутствующие в запросе.

Шаг 1 - подтвердите, что сгенерированный URL работает

Я бы попробовал загрузить через curl / postman, чтобы увидеть, работает ли URL.

curl -X PUT -T ~/Downloads/car.jpg https://s3.us-west-2.amazonaws.com/pics.amazon-clone.io/b1bdb5e3-7f64-49f7-b779-11b3f67317ee.jpg?Content-Type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIASGDJJ5ZLUVPMUYMQ%2F20200129%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20200129T165522Z&X-Amz-Expires=900&X-Amz-Signature=b230c9a40065585307e150655466bbab3d0d99aa43f8620377ab977eb1c7234c&X-Amz-SignedHeaders=host%3Bx-amz-acl&x-amz-acl=public-read

Шаг 2 - подтвердить * работает ли reactjs запрос выборки

Если вы можете подтвердить, что шаг 1 работает, то вы можете проверить фактические заголовки, отправляемые с запросом, с помощью вкладки сети браузера. Посмотрите, отправляет ли код какие-либо дополнительные заголовки без вашего ведома.

Надеюсь, это поможет.

0 голосов
/ 29 января 2020

Когда вы получаете сообщение об ошибке OPTIONS -> CORS Policy от AWS S3 Buckets, это означает, что ваша конфигурация корзины не позволяет вам загружать изображения.

Чтобы исправить это, вы должны обновить конфигурации разрешений вашей корзины.

Чтобы сделать это go для вашего контейнера -> вкладка разрешений -> вкладка CORS

Затем вставьте туда следующий код:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin><YOUR_DOMAIN></AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Не забудьте заменить <YOUR_DOMAIN> на свой домен, очевидно: P

If you want to allow all domains just replace this line

<AllowedOrigin><YOUR_DOMAIN></AllowedOrigin> 

with this

<AllowedOrigin>*</AllowedOrigin>
...