19

I am getting en error when creating S3 client from class S3 in newer v3 of aws-sdk javascript.

I add aws config parameters including credentials obtained from aws sts when user gets authenticated (assuming a role with permission to call getObject) at service-level (when instantiating S3 class) along with other parameters. See my code below:

const { S3, ... } = require("@aws-sdk/client-s3");

someFunc();
function someFunc(authUserCredentials) {
 ...
 try {

   const { AccessKeyid, SecretKey, SessionToken } = authUserCredentials;
   const s3Client = new S3({
                      signatureVersion: 'v4',
                      accessKeyId: AccessKeyId,
                      secretAccessKey: SecretKey,
                      sessionToken: SessionToken,
                      region: 'us-east-1',
   });

   console.log(s3Client.config);
   ...

 }catch(e) {
     console.error(e);
 }
}

I checked the class S3 code in aws-sdk-js-v3 repo, and there doesn't seem to be no 'Credential' constructor config argument required. Am I doing something wrong?

Waleed93
  • 1,130
  • 2
  • 15
  • 24

4 Answers4

22

Just to clarify Chris Williams's answer combined with @Waleed93's second comment, what used to work with the AWS Javascript SDK v2 is:

import S3 from 'aws-sdk/clients/s3';

const AccessKeyId = xxxxx,
      SecretKey = yyyyyyyy,
      SessionToken = zzzzzzzzzz;

const s3Client = new S3({
    apiVersion: '2006-03-01',
    region: 'us-east-1',
    accessKeyId: AccessKeyId,
    secretAccessKey: SecretKey,
    sessionToken: SessionToken
});

For SDK v3, the constructor no longer accepts individual credential parameters but does take a "credentials" object as a parameter. What works is:

const { S3 } = require('@aws-sdk/client-s3');

const AccessKeyId = xxxxx,
      SecretKey = yyyyyyyy,
      SessionToken = zzzzzzzzzz;

const creds = {
    accessKeyId: AccessKeyId,
    secretAccessKey: SecretKey,
    sessionToken: SessionToken
};

const s3Client = new S3({
    apiVersion: '2006-03-01',
    region: 'us-east-1',
    credentials: creds
});

This change is nowhere to be found in the AWS SDK documentation, class reference, or Developer Guide for SDK Version 3. Thank you to Chris and @Waleed93 for figuring it out.

JJJSchmidt
  • 820
  • 6
  • 13
  • The accepted answer is correct in that the accessKeyId, secretAccessKey, and sessionToken parameters are still present in the constructor according to the docs. However, I do do not believe it is still used by the underlying code as I've encountered missing credentials error by doing so. Using this answer above is the correct method of authenticating for JavaScript SDK v3. Thank you @JJJSchmidt, you've help me get unstuck after banging my head for 45 mins! – Alex May 06 '22 at 21:55
6

According to the documentation for the constructor these arguments are valid.

There is still an argument name for the Credential object with the name credentials. If you instantiate a AWS.Credentials object you can pass this into that argument.

Chris Williams
  • 32,215
  • 4
  • 30
  • 68
  • Right. But how to create AWS.Credentials object in v3 sdk? I cannot see any api for it – Waleed93 Jun 27 '20 at 16:29
  • You can use the constructor here: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Credentials.html#constructor-property. You'll need to require, I think its accessible via `require('aws-sdk/global');` but not 100% sure. – Chris Williams Jun 27 '20 at 16:36
  • 3
    My bad, it's just an object. I added `accessKeyId`, `secretAccessKey` and `sessionToken` keys' values and it works. Thanks! What you're proposing above is with sdk v2, not with v3 – Waleed93 Jun 27 '20 at 17:03
5

The value of credentials should be an object containing your credentials passed into the config as below:

import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3'

const CREDENTIAL = {
  accessKeyId: 'accesKeyIdString',
  secretAccessKey: 'secretAccessKeyIdString',
};

const REGION: 'aws region';
const s3Client = new S3Client({region: REGION, credentials: CREDENTIAL});
MD Ashik
  • 9,117
  • 10
  • 52
  • 59
Rex Osariemen
  • 151
  • 2
  • 4
2

I'm going to expand on this a bit more with my own experiences. I was working through this guide from AWS for "Viewing Photos in an Amazon S3 Bucket from a Browser" (giving guest users -- no login --, the ability to interact with s3 objects through a cognito identity pool). The resources in the AWS guide are for the V2 version of the SDK. So, I had to do a lot of digging to set it up for V3.

So, in short I'm doing the following:

  • using V3 SDK for javascript
  • getting credentials from an AWS Cognito Identity Pool (see linked guide)
  • using those credentials in the new S3({ ... credentials })
import { fromCognitoIdentityPool } from "@aws-sdk/credential-providers";
import { S3, ListObjectsCommand } from "@aws-sdk/client-s3";

// get identity pool creds (in my case)
const credentials = fromCognitoIdentityPool({
  identityPoolId: "your-identity-pool-id",
  clientConfig: { region: "your-region" },
});

// initialize V3 SDK S3 class
const client = new S3({
  apiVersion: "2006-03-01",
  region: "your-region",
  // plug in credentials
  credentials,
});

...

This was my specific use case. Here are the resources I found really helpful.

kevin
  • 2,707
  • 4
  • 26
  • 58