Vaibhav Agarwal
Vaibhav Agarwal

Reputation: 975

Unable to download file from Amazon S3

I am using following code to download an image from Amazon S3:

 router.post('/image-upload', function (req, res, next) {

    if (!req.files)
        return res.status(400).send('No files were uploaded.');

    var file = req.files['image_' + req.session.sessID];

    AWS.config.loadFromPath(<credentials_path>);

    var s3 = new AWS.S3();

    var params = {Bucket: credentials.aws_s3.bucket_name, Key: req.session.email, Body: file.data};

    s3.putObject(params, function(err, data) {

        if (err) {
            console.log(err)

        } else {

            var options = {
                Bucket: credentials.aws_s3.bucket_name,
                Key: req.session.email
            };

            var url = s3.getSignedUrl('getObject', options);
            console.log(url);

        }
    });
});

I am getting url in following form:

https://[S3 BUCKET].s3.ap-south-1.amazonaws.com/[KEY]?X-Amz-Algorithm=[VALUE]&amp;X-Amz-Credential=[VALUE]&amp;X-Amz-Date=20170427T111724Z&amp;X-Amz-Expires=60&amp;X-Amz-Signature=[VALUE]&amp;X-Amz-SignedHeaders=[VALUE]

However, when I try to open this link in browser, I am getting following error:

<Error>
<Code>AuthorizationQueryParametersError</Code>
<Message>
Query-string authentication version 4 requires the X-Amz-Algorithm, X-Amz-Credential, X-Amz-Signature, X-Amz-Date, X-Amz-SignedHeaders, and X-Amz-Expires parameters.
</Message>
<RequestId>29819210D89C8877</RequestId>
<HostId>
aPpmRMYB7QCog4UDqs1j2rCdY3cy5H8u3kGE8nv2qXF6Y2iATPNquz+MQNdvr3zZ1ceRydRplq0=
</HostId>
</Error>

I am unable to understand why this error, as the returned url has all the requisite query parameters. Can anyone please help??

Upvotes: 0

Views: 683

Answers (1)

David Kelley
David Kelley

Reputation: 193

Note: You must ensure that you have static or previously resolved credentials if you call this method synchronously (with no callback), otherwise it may not properly sign the request. If you cannot guarantee this (you are using an asynchronous credential provider, i.e., EC2 IAM roles), you should always call this method with an asynchronous callback.

Try instead to retrieve the signed url inside the methods callback function.

s3.getSignedUrl('getObject', options, function(err, url) {
  console.log(url);
});

Upvotes: 1

Related Questions