Nodejs AWS SDK S3 Buat URL yang Ditentukan

112

Saya menggunakan NodeJS AWS SDK untuk menghasilkan URL S3 presigned. Dokumen memberikan contoh menghasilkan URL yang telah ditetapkan sebelumnya .

Ini kode persis saya (dengan info sensitif dihilangkan):

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 yang dihasilkan terlihat seperti ini:

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

Saya menyalin URL itu ke browser saya dan mendapatkan tanggapan berikut:

<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>

Saya tahu ember itu ada. Saat saya menavigasi ke item ini melalui AWS Web GUI dan mengklik dua kali di atasnya, ini akan membuka objek dengan URL dan berfungsi dengan baik:

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]

Jadi saya dibuat percaya bahwa saya pasti melakukan sesuatu yang salah dengan cara saya menggunakan SDK.

Dustin
sumber
1
Periksa URL yang Anda buat dengan hati-hati. NoSuchBucketberarti nama keranjang yang ditampilkan https://>>>here<<<.s3-us-west-2.amazonaws.comdi URL tidak ada. Tidak ada dalam proses penandatanganan, kebijakan, izin, kunci, atau rahasia Anda yang dapat menghasilkan kesalahan khusus ini.
Michael - sqlbot
8
Tautan ke contoh dokumen telah dipindahkan ke docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/…
Joël
@Dustin seberapa aman jika ACCESS Key terekspos di url dan apakah url berubah pada setiap panggilan fungsi
kailash yogeshwar
Tidak aman untuk meletakkan secretAccessKey di tempat umum, seperti URL dan ya saya yakin URL berubah setiap saat. @kailashyogeshwar
Dustin
5
Bagi mereka yang datang ke sini seperti saya dan tidak mendapatkan jawaban pasti, inilah yang saya butuhkan. Ada versi tanda tangan berbeda yang digunakan di setiap URL di atas. Setel versi tanda tangan sebelum membuat instans S3 atau setel di konfigurasi S3. new AWS.S3({ signatureVersion: 'v4' })memaksa Signature Versi 4. Ini adalah persyaratan bagi saya dengan objek terenkripsi SSE KMS.
Eric E.

Jawaban:

100

Dustin,

Kode Anda benar, periksa kembali berikut ini:

  1. Kebijakan akses keranjang Anda.

  2. Izin keranjang Anda melalui kunci API Anda.

  3. Kunci dan rahasia API Anda.

  4. Nama dan kunci keranjang Anda.

Reza Mousavi
sumber
92
Yang memalukan, saya salah ketik di nama keranjang saya.
Dustin
36
Klasik. Terjadi demi yang terbaik bagi kita.
Vlad A. Ionescu
2

Saya memiliki kasus penggunaan di mana menggunakan node.js; Saya ingin mendapatkan objek dari s3 dan mendownloadnya ke beberapa lokasi sementara dan kemudian memberikannya sebagai lampiran ke layanan pihak ketiga! Beginilah cara saya memecahkan kode:

  1. dapatkan url yang ditandatangani dari s3
  2. membuat panggilan istirahat untuk mendapatkan objek
  3. tulis itu ke lokasi lokal

Ini dapat membantu siapa pun; jika ada kasus penggunaan yang sama; chekout link di bawah ini ; https://medium.com/@prateekgawarle183/fetch-file-from-aws-s3-using-pre-signed-url-and-store-it-into-local-system-879194bfdcf4

Prateek G
sumber
0

Karena pertanyaan ini sangat populer dan jawaban paling populer adalah mengatakan kode Anda benar, tetapi ada sedikit masalah dalam kode yang mungkin menyebabkan masalah yang membuat frustrasi. Jadi, inilah kode yang berfungsi

    AWS.config.update({ 
        accessKeyId: ':)))',
        secretAccessKey: ':DDDD',
        region: 'ap-south-1',
        signatureVersion: 'v4'
    });

    const s3 = new AWS.S3()
    const myBucket = ':)))))'
    const myKey = ':DDDDDD'
    const signedUrlExpireSeconds = 60 * 5

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

    console.log(url);

Perbedaan yang mencolok adalah objek s3 dibuat setelah pembaruan konfigurasi, tanpa ini konfigurasi tidak efektif dan url yang dihasilkan tidak berfungsi.

Avinash
sumber
-1

Coba fungsi ini dengan janji.

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()
Ankit Kumar Rajpoot
sumber