Nodejs AWS SDK S3 Önceden İmzalanmış URL Oluştur


120

Önceden imzalanmış bir S3 URL'si oluşturmak için NodeJS AWS SDK'yı kullanıyorum. Dokümanlar, önceden imzalanmış bir URL oluşturmaya bir örnek verir .

İşte tam kodum (hassas bilgiler hariç):

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)

Oluşturan URL şuna benzer:

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

Bu URL'yi tarayıcıma kopyalayıp aşağıdaki yanıtı alıyorum:

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

Kovanın var olduğunu biliyorum. Bu öğeye AWS Web GUI üzerinden gidip üzerine çift tıkladığımda, nesneyi URL ile açar ve gayet iyi çalışıyor:

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]

Bu yüzden, SDK'yı nasıl kullandığımla ilgili yanlış bir şeyler yapıyor olmam gerektiğine inanıyorum.


1
Oluşturulan URL'nizi dikkatlice inceleyin. URL'de NoSuchBucketgösterilen paket adının https://>>>here<<<.s3-us-west-2.amazonaws.comolmadığı anlamına gelir . İmza sürecinizdeki, politikanızdaki, izinlerinizdeki, anahtarınızdaki veya sırrınızdaki hiçbir şey bu belirli hatayı oluşturamaz.
Michael - sqlbot


@Dustin, ACCESS Anahtarının url'de gösterilmesi ve her işlev çağrısında
url'nin

SecretAccessKey'i URL gibi halka açık bir yere koymak güvenli değil ve evet URL'nin her seferinde değiştiğine inanıyorum. @kailashyogeshwar
Dustin

5
Buraya benim yaptığım gibi gelen ve tam cevabı alamayanlar için ihtiyacım olan buydu. Yukarıdaki URL'lerin her birinde farklı bir imza sürümü kullanılmaktadır. S3 örneğini oluşturmadan önce imza sürümünü ayarlayın veya S3'ün yapılandırmasına ayarlayın. new AWS.S3({ signatureVersion: 'v4' })İmza Sürümü 4'ü zorlar. Bu, SSE KMS şifreli nesne ile benim için bir gereklilikti.
Eric E.

Yanıtlar:


104

Dustin,

Kodunuz doğru, aşağıdakileri iki kez kontrol edin:

  1. Paket erişim politikanız.

  2. API anahtarınız aracılığıyla paket izniniz.

  3. API anahtarınız ve sırrınız.

  4. Paket adınız ve anahtarınız.


96
Utanç verici bir şekilde, kova adımda bir yazım hatası vardı.
Dustin

37
Klasik. En iyimizin başına geliyor.
Vlad A. Ionescu

4

Bu soru çok popüler olduğundan ve en popüler cevap kodunuzun doğru olduğunu söylemektir, ancak kodda sinir bozucu bir soruna yol açabilecek bir miktar sorun vardır. İşte çalışan bir kod

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

Göze çarpan fark, s3 nesnesinin yapılandırma güncellemesinden sonra yaratılmasıdır, bu olmadan yapılandırma etkili olmaz ve oluşturulan url çalışmaz.


2

Node.js kullandığım bir kullanım durumum vardı; S3'ten nesne almak ve onu geçici bir yere indirmek ve ardından üçüncü taraf hizmete ek olarak vermek istedim! Kodu böyle kırdım:

  1. s3'ten imzalanmış url alın
  2. nesneyi almak için dinlenme çağrısı yap
  3. bunu yerel konuma yaz

Herkese yardımcı olabilir; aynı kullanım durumu varsa; aşağıdaki linkten kontrol edin ; https://medium.com/@prateekgawarle183/fetch-file-from-aws-s3-using-pre-signed-url-and-store-it-into-local-system-879194bfdcf4


-1

Bu işlevi söz vererek deneyin.

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()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.