» npm install @aws-sdk/client-s3
amazon s3 - Is this a safe way to use aws-sdk on client side? - Stack Overflow
Safe way to use aws-sdk lib on client side
amazon web services - How to set credentials in AWS SDK v3 JavaScript? - Stack Overflow
How dose AWS manages all of their SDKs?
Videos
I have read different opinions so I'd like expert ones. My question is basic:
If I create a react app (only client side), from where I'm planning to read a s3 object, is the following a safe approach or my credentials will be somehow exposed? My env variable would only be stored in Netlify.
I'm asking this because I had a similar setup and my AWS was compromised (but I'm unsure if this approach was the reason).
aws-exports.js
import { config } from 'aws-sdk'
const AWSConfig = {
accessKeyId: process.env.REACT_APP_AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.REACT_APP_AWS_SECRET_ACCESS_KEY,
region: process.env.REACT_APP_AWS_REGION,
}
config.update(AWSConfig)s3.js
import { S3 } from 'aws-sdk'
class S3Singleton {
static instance = undefined
static async getInstance() {
if (S3Singleton.instance) {
return S3Singleton.instance
}
S3Singleton.instance = await S3Singleton.createInstance()
return S3Singleton.instance
}
static createInstance = async () => {
return new S3({
apiVersion: process.env.REACT_APP_AWS_API_VERSION,
region: process.env.REACT_APP_AWS_REGION,
params: { Bucket: process.env.REACT_APP_AWS_BUCKET },
})
}
}
export default S3Singleton
The s3 object reading
import S3Singleton from './s3'
export const getXFile = async () => {
try {
const s3 = await S3Singleton.getInstance()
return await new Promise((resolve, reject) => {
s3.getObject(
{
Bucket: process.env.REACT_APP_BUCKET,
Key: "xfile.json",
},
(err, data) => {
if (err) reject(err)
if (data) resolve(JSON.parse(data.Body.toString()))
},
)
})
} catch (e) {
console.log(e)
}
}
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
},
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)
}
» npm install aws-sdk-client-mock