Nodejs AWS SDK S3 Створити призначену URL-адресу


112

Я використовую NodeJS AWS SDK для генерації призначеної URL-адреси S3. Документи наводять приклад генерації призначеної URL-адреси .

Ось мій точний код (з недопущеною конфіденційною інформацією):

const AWS = require('aws-sdk')

const s3 = new AWS.S3()
AWS.config.update({accessKeyId: 'id-omitted', secretAccessKey: 'key-omitted'})

// Tried with and without this. Since s3 is not region-specific, I don't
// think it should be necessary.
// AWS.config.update({region: 'us-west-2'})

const myBucket = 'bucket-name'
const myKey = 'file-name.pdf'
const signedUrlExpireSeconds = 60 * 5

const url = s3.getSignedUrl('getObject', {
    Bucket: myBucket,
    Key: myKey,
    Expires: signedUrlExpireSeconds
})

console.log(url)

Створена URL-адреса виглядає так:

https://bucket-name.s3-us-west-2.amazonaws.com/file-name.pdf?AWSAccessKeyId=[access-key-omitted]&Expires=1470666057&Signature=[signature-omitted]

Я копіюю цю URL-адресу у свій браузер і отримую таку відповідь:

<Error>
  <Code>NoSuchBucket</Code>
  <Message>The specified bucket does not exist</Message>
  <BucketName>[bucket-name-omitted]</BucketName>
  <RequestId>D1A358D276305A5C</RequestId>
  <HostId>
    bz2OxmZcEM2173kXEDbKIZrlX508qSv+CVydHz3w6FFPFwC0CtaCa/TqDQYDmHQdI1oMlc07wWk=
  </HostId>
</Error>

Я знаю, що відро існує. Коли я переходжу до цього елемента через веб-графічний інтерфейс AWS і двічі клацну на ньому, він відкриває об’єкт із URL-адресою і працює чудово:

https://s3-us-west-2.amazonaws.com/[bucket-name-omitted]/[file-name-omitted].pdf?X-Amz-Date=20160808T141832Z&X-Amz-Expires=300&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Signature=[signature-omitted]&X-Amz-Credential=ASIAJKXDBR5CW3XXF5VQ/20160808/us-west-2/s3/aws4_request&X-Amz-SignedHeaders=Host&x-amz-security-token=[really-long-key]

Тому мене змушують вважати, що я, мабуть, роблю щось не так із тим, як я використовую SDK.


1
Уважно вивчіть створену URL-адресу. NoSuchBucketозначає, що назва сегмента, вказана https://>>>here<<<.s3-us-west-2.amazonaws.comв URL-адресі, не існує. Ніщо у вашому процесі підписання, політиці, дозволах, ключі та секрети не може призвести до цієї конкретної помилки.
Майкл - sqlbot

8
Посилання на приклад документа було переміщено на docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/…
Джоел,

@Dustin, наскільки безпечно, якщо клавіша ACCESS виставляється в url і змінює url при кожному виклику функції
kailash yogeshwar

Небезпечно розміщувати secretAccessKey у громадському місці, наприклад, за URL-адресою, і так, я вважаю, що URL-адреса змінюється кожного разу. @kailashyogeshwar
Дастін

5
Для тих, хто прийшов сюди, як я, і не отримав точної відповіді, це те, що мені потрібно. У кожній із зазначених вище URL-адрес використовується інша версія підпису. Встановіть версію підпису перед створенням екземпляра S3 або встановіть у конфігурації S3. new AWS.S3({ signatureVersion: 'v4' })змушує Підпис Версії 4. Це була вимога для мене із зашифрованим об’єктом SSE KMS.
Ерік Е.

Відповіді:


99

Дастін,

Ваш код правильний, перевірте наступне:

  1. Ваша політика доступу до сегмента.

  2. Ваш дозвіл на сегмент через ваш ключ API.

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

  4. Ім'я та ключ вашого відра.


92
Прикро, але в моєму відрі була помилка.
Дастін,

36
Класичний. Трапляється з найкращими з нас.
Влад А.Іонеску,

2

У мене був випадок використання, коли використання node.js; Я хотів отримати об'єкт з s3 і завантажити його в якесь тимчасове місце, а потім віддати в якості додатка до сторонньої служби! Ось як я зламав код:

  1. отримати підписану URL-адресу з s3
  2. зробити дзвінок відпочинку, щоб отримати об'єкт
  3. напишіть це в місцевому розташуванні

Це може допомогти кожному; якщо є той самий варіант використання; chekout нижче посилання ; https://medium.com/@prateekgawarle183/fetch-file-from-aws-s3-using-pre-signed-url-and-store-it-into-local-system-879194bfdcf4


-1

Спробуйте цю функцію з обіцянкою.

const AWS = require("aws-sdk");
const s3 = new AWS.S3({
  accessKeyId: 'AK--------------6U',
  secretAccessKey: 'kz---------------------------oGp',
  Bucket: 'bucket-name'
});

const getSingedUrl = async () => {    
  const params = {
    Bucket: 'bucket_name',
    Key: 'file-name.pdf',
    Expires: 60 * 5
  };

  try {
    const url = await new Promise((resolve, reject) => {
      s3.getSignedUrl('getObject', params, (err, url) => {
        err ? reject(err) : resolve(url);
      });
    });
    console.log(url)
  } catch (err) {
    if (err) {
      console.log(err)
    }
  }
}


getSingedUrl()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.