Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set credentials in AWS SDK v3 JavaScript?

I am scouring the documentation, and it only provides pseudo-code of the credentials for v3 (e.g. const client = new S3Client(clientParams)

How do I initialize an S3Client with the bucket and credentials to perform a getSignedUrl request? Any resources pointing me in the right direction would be most helpful. I've even searched YouTube, SO, etc and I can't find any specific info on v3. Even the documentation and examples doesn't provide the actual code to use credentials. Thanks!

As an aside, do I have to include the fake folder structure in the filename, or can I just use the actual filename? For example: bucket/folder1/folder2/uniqueFilename.zip or uniqueFilename.zip

Here's the code I have so far: (Keep in mind I was returning the wasabiObjKey to ensure I was getting the correct file name. I am. It's the client, GetObjectCommand, and getSignedUrl that I'm having issues with.

exports.getPresignedUrl = functions.https.onCall(async (data, ctx) => {
  const wasabiObjKey = `${data.bucket_prefix ? `${data.bucket_prefix}/` : ''}${data.uid.replace(/-/g, '_').toLowerCase()}${data.variation ? `_${data.variation.replace(/\./g, '').toLowerCase()}` : ''}.zip`
  const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3')
  const s3 = new S3Client({
    bucketEndpoint: functions.config().s3_bucket.name,
    region: functions.config().s3_bucket.region,
    credentials: {
      secretAccessKey: functions.config().s3.secret,
      accessKeyId: functions.config().s3.access_key
    }
  })
  const command = new GetObjectCommand({
    Bucket: functions.config().s3_bucket.name,
    Key: wasabiObjKey,
  })
  const { getSignedUrl } = require("@aws-sdk/s3-request-presigner")
  const url = getSignedUrl(s3, command, { expiresIn: 60 })
  return wasabiObjKey
})
like image 507
Joel Hager Avatar asked Sep 01 '25 22:09

Joel Hager


2 Answers

There is a credential chain that provides credentials to your API calls from the SDK https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html

Loaded from AWS Identity and Access Management (IAM) roles for Amazon EC2

Loaded from the shared credentials file (~/.aws/credentials)

Loaded from environment variables

Loaded from a JSON file on disk

Other credential-provider classes provided by the JavaScript SDK

You can embed the credential inside your source code but it's not the prefered way

new S3Client(configuration: S3ClientConfig): S3Client

Where S3ClientConfig contain a credentials property

https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/modules/credentials.html

    const { S3Client,GetObjectCommand } = require("@aws-sdk/client-s3");
    
    let client = new S3Client({
        region:'ap-southeast-1',
        credentials:{
            accessKeyId:'',
            secretAccessKey:''
        }
    });
    
    (async () => {
      const response = await client.send(new GetObjectCommand({Bucket:"BucketNameHere",Key:"ObjectNameHere"}));
      console.log(response);
    })();

Sample answer

  '$metadata': {
    httpStatusCode: 200,
    requestId: undefined,
    extendedRequestId: '7kwrFkEp3lEnLU+OtxjrgdmS6gQmvPdbnqqR7I8P/rdFrUPBkdKYPYykWivuHPXCF1IHgjCIbe8=',
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  },
like image 180
qkhanhpro Avatar answered Sep 03 '25 12:09

qkhanhpro


Here's a simple approach I use (in Deno) for testing (in case you don't want to go the signedUrl approach and just let the SDK do the heavy lifting for you):

import { config as env } from 'https://deno.land/x/dotenv/mod.ts' // https://github.com/pietvanzoen/deno-dotenv
import { S3Client, ListObjectsV2Command } from 'https://cdn.skypack.dev/@aws-sdk/client-s3' // https://github.com/aws/aws-sdk-js-v3

const {AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY} = env()

// https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/modules/credentials.html
const credentials = {
    accessKeyId: AWS_ACCESS_KEY_ID,
    secretAccessKey: AWS_SECRET_ACCESS_KEY,
}

// https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/s3clientconfig.html
const config = {
    region: 'ap-southeast-1',
    credentials,
}

// https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/classes/s3client.html
const client = new S3Client(config)

export async function list() {
    // https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/listobjectsv2commandinput.html
    const input = {
        Bucket: 'BucketNameHere'
    }

    // https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/classes/command.html
    const cmd = new ListObjectsV2Command(input)
    
    // https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/classes/listobjectsv2command.html
    return await client.send(cmd)
}
like image 23
Billy Clark Avatar answered Sep 03 '25 12:09

Billy Clark