I'm new to the AWS SDK and I'm trying to retrieve a presiggned URL for a private object in S3.
I am finding that my promise is resolving with a value of undefined
. I suspect that my awsBucket
variable is not leveraging my awsConfig
but I'm not sure how to get the two to communicate.
My goal is to click a button that updates the src
of my img
to display an image that is stored in S3. Any help is greatly appreciated.
Below is my code, where you can assume the secret/access keys are populated correctly.
HTML:
<html>
<head>
<script type="text/javascript" src="lib/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="lib/bootstrap/dist/js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/tableau.extensions.1.latest.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<!-- AWS SDK-->
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.910.0.min.js"></script>
<link rel="stylesheet" type="text/css" href="lib/bootstrap/dist/css/bootstrap.min.css">
<!-- Font awesome icons-->
<script src="https://kit.fontawesome.com/d8651426bf.js" crossorigin="anonymous"></script>
<title>Image from S3</title>
</head>
<body>
<div class="" id="divMain">
<p>
<button id="refreshImageButton" class="btn btn-secondary">
<i class="fa fa-repeat"></i>
</button>
</p>
<img
id="displayImage"
src=""
alt="Placeholder"
>
</div>
</body>
</html>
JS:
var awsAccessKeyID = 'my-access-key';
var awsSecretAccessKey = 'my-secret-key';
var awsBucketName = 'bucket-name';
const URL_EXPIRATION_TIME = 60; // in seconds
var awsRegion = 'eu-west-2'; // Is this the right way to write the AWS Region?
$(document).ready(initialise());
// This function is called when the page first loads
function initialise() {
console.log('Test')
// Refresh image button
$("#refreshImageButton").click(function() {
let imagePath='1.jpg'
refreshImage(imagePath);
});
}, function () { console.log('Error while Initializing: ' + err.toString()); });
}
// This function refreshes the image using an incoming path from the data
function refreshImage(imagePath){
console.log(`Image path: ${imagePath}`)
let preSignedURL = generatePreSignedGetUrl(imagePath, 'jpg')
console.log(preSignedURL)
$("#displayImage").attr("src",preSignedURL);
}
// This function generated the pre signed URL that can access a private object in S3
function generatePreSignedGetUrl( fileName , fileType) {
return new Promise(function(resolve, reject){
let awsConfig = new AWS.Config();
awsConfig.update({
accessKeyId: awsAccessKeyID,
secretAccessKey: awsSecretAccessKey,
})
let awsBucket = new AWS.S3();
let awsBucket = new AWS.S3({
params: { Bucket: awsBucketName},
region: awsRegion,
})
awsBucket.getSignedUrl('getObject', {
Key: fileName,
ContentType: fileType,
Expires: URL_EXPIRATION_TIME
} , (err , url) => {
resolve(url) // API Response Here
});
})
};
In the end, I abandoned this approach in favour of a NodeJS backend. Here is my complete and working code:
// Use modules
const config = require('./config');
const AWS = require('aws-sdk');
AWS.config.update({
accessKeyId: config.awsAccessKeyID
, secretAccessKey: config.awsSecretAccessKey
, region: config.awsRegion
});
const s3 = new AWS.S3({signatureVersion: 'v4'});
// Create the parameters for calling listObjects
var bucketParams = {
Bucket : 'BUCKETNAME',
};
// Call S3 to obtain a list of the objects in the bucket
// This is a good way to test the authentication is working
s3.listObjects(bucketParams, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log("Success", data);
}
});
var awsGeneratePresignedURLsBackend = function(app) {
// Enable CORS
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
next();
});
// Connection Test
app.get('/ConnectionTest', function (req, res) {
res.send('Connected');
});
// Slack App Connection Test
app.post('/generatePreSignedGetUrl', function (req, res) {
console.log("")
console.log("--------------------------")
console.log(`endpoint: generatePreSignedGetUrl`)
console.log(`type: POST`)
console.log(`statusCode: ${res.statusCode}`)
const myBucket = req.body.awsBucketName
const myKey = req.body.fileName
console.log(`Bucket: ${myBucket}`);
console.log(`Key: ${myKey}`);
const url = s3.getSignedUrl('getObject', {
Bucket: myBucket,
Key: myKey
});
res.send(url)
console.log(`url: ${url}`)
res.end()
});
}
module.exports = awsGeneratePresignedURLsBackend;