AWS S3 Создание подписанных URL-адресов '' AccessDenied '' - PullRequest
0 голосов
/ 05 октября 2018

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

Загрузка

const s3bucket = new AWS.S3({
    accessKeyId: 'my-access-key-id',
    secretAccessKey: 'my-secret-access-key',
    Bucket: 'my-bucket-name',
})
const uploadParams = {
    Body: file.data,
    Bucket: 'my-bucket-name',
    ContentType: file.mimetype,
    Key: `files/${file.name}`,
}
s3bucket.upload(uploadParams, function (err, data) {
    // ...
})

Загрузка

const url = s3bucket.getSignedUrl('getObject', {
    Bucket: 'my-bucket-name',
    Key: 'file-key',
    Expires: 300,
})

Выпуск

При открытии URL я получаю следующее:

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
    <Code>AccessDenied</Code>
    <Message>
        There were headers present in the request which were not signed
    </Message>
    <HeadersNotSigned>host</HeadersNotSigned>
    <RequestId>D63C8ED4CD8F4E5F</RequestId>
    <HostId>
        9M0r2M3XkRU0JLn7cv5QN3S34G8mYZEy/v16c6JFRZSzDBa2UXaMLkHoyuN7YIt/LCPNnpQLmF4=
    </HostId>
</Error>

Мне не удается найти ошибку.Буду очень признателен за любую помощь:)

Ответы [ 3 ]

0 голосов
/ 08 октября 2018

Ваш код выглядит хорошо, но я думаю, что вам не хватает параметра signatureVersion: 'v4' при создании объекта s3bucket.Попробуйте приведенный ниже обновленный код.

const s3bucket = new AWS.S3({
    signatureVersion: 'v4',
    accessKeyId: 'my-access-key-id',
    secretAccessKey: 'my-secret-access-key',
    Bucket: 'my-bucket-name',
})
const uploadParams = {
    Body: file.data,
    Bucket: 'my-bucket-name',
    ContentType: file.mimetype,
    Key: `files/${file.name}`,
}
s3bucket.upload(uploadParams, function (err, data) {
    // ...
})
const url = s3bucket.getSignedUrl('getObject', {
    Bucket: 'my-bucket-name',
    Key: 'file-key',
    Expires: 300,
})

Для получения дополнительной информации о signatureVersion: 'v4' см. Ссылки ниже

https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html

https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html

Вы также можете попробовать следующую библиотеку nodejs, которая создает presigned url

https://www.npmjs.com/package/aws-signature-v4

0 голосов
/ 22 февраля 2019

У меня продолжалась похожая проблема, но моя была из-за настроек региона.В нашем бэкэнде у нас были некоторые настройки для приложения.

Один из которых был "region": "us-west-2", поэтому предопределенный URL был создан с этим регионом, но когда он вызывался во внешнем интерфейсе, регион был установлен на "us-west-1".

Изменение его на такое же исправило проблему.

0 голосов
/ 08 октября 2018

Ваш код верен, дважды проверьте следующее:

  1. Политика доступа к вашему ведру.

  2. Ваше разрешение на ведение через ваш ключ API.

  3. Ваш ключ и секрет API.

  4. Имя и ключ вашего сегмента.

ДляВы можете использовать следующую политику:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::bucket/*"
        }
    ]
}

Измените корзину на свое имя корзины.

Для пользователей и прав доступа к ключу (# 2) вы должны следоватьэти шаги:

1-Goto AWS Identity and Access Management (IAM), нажмите ссылку «Политики» и нажмите кнопку «Создать политику».

enter image description here

2-Выберите вкладку JSON.

enter image description here

3-Введите следующую инструкцию, убедитесь, что изменили имя корзины и нажмите "Кнопка "Просмотреть политику".

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::YOURBUCKETNAME"
        }
    ]
}

enter image description here

4 - Введите название своей политики и нажмите кнопку "Создать политику".

enter image description here

5-Нажмите ссылку «Пользователи» и найдите свое текущее имя пользователя (для этого у вас уже есть ключ доступа и секрет)

enter image description here

6-Click on «add»Кнопка «Права доступа».

enter image description here

7 - Добавьте политику, созданную на предыдущем шаге, и сохраните.

enter image description here

Наконец, убедитесь, что ваша корзина недоступна из Public, добавьте в файл правильный тип содержимого и установите signatureVersion: 'v4'

Окончательный код должен быть таким, спасибо @Vaisakh PS:

const s3bucket = new AWS.S3({
    signatureVersion: 'v4',
    accessKeyId: 'my-access-key-id',
    secretAccessKey: 'my-secret-access-key',
    Bucket: 'my-bucket-name',
})
const uploadParams = {
    Body: file.data,
    Bucket: 'my-bucket-name',
    ContentType: file.mimetype,
    Key: `files/${file.name}`,
}
s3bucket.upload(uploadParams, function (err, data) {
    // ...
})
const url = s3bucket.getSignedUrl('getObject', {
    Bucket: 'my-bucket-name',
    Key: 'file-key',
    Expires: 300,
})
...