ChrisRich
ChrisRich

Reputation: 8716

Upload file to Amazon S3 using HTTP PUT

I work in a financial institution and for security reasons my employer cannot give out the access key id and the access key secret to the AWS account. This means I can't use aws-sdk.

As a next option, would it be possible to upload files using HTTP PUT to a public S3 bucket without using the AWS-SDK that requires the access key id and the access key secret?

I had a look at this answer: How to upload a file using a rest client for node

And was thinking of this approach:

var request = require('request');

var options = {
    method: 'PUT',
    preambleCRLF: true,
    postambleCRLF: true,
    uri: 'https://s3-ap-southeast-2.amazonaws.com/my-bucket/myFile.pdf',
    multipart: [
        {
            'content-type': 'application/pdf'
            body: fs.createReadStream('/uploads/uploaded-file.pdf') 
        }
    ]
}

request(options, function(err, response, body){

    if(err){
        return console.log(err);
    }

    console.log('File uploaded to s3');
});

Could that work?

Upvotes: 1

Views: 8803

Answers (2)

josesuero
josesuero

Reputation: 3760

This is a bit old but for anyone looking for the same you can now use a pre signed url to achieve this, how it works is you create a preSigned url on your server, share it with the client and use this to upload the file to s3

server to generate an url:

const AWS = require('aws-sdk')

const s3 = new AWS.S3({
  region: 'us-east-1',
  signatureVersion: 'v4'
})
AWS.config.update({accessKeyId: 'access-key', secretAccessKey: 'access-pass'})

const myBucket = 'clearg-developers'
const myKey = 'directory/newFile.zip'
const signedUrlExpireSeconds = 60 * 5 //seconds the url expires

const url = s3.getSignedUrl('putObject', {
    Bucket: myBucket,
    Key: myKey,
    Expires: signedUrlExpireSeconds

});
return url

and on the client from node you can put to get an empty body:

var fileName = '/path/to/file.ext';
var stats = fs.statSync(fileName);
fs.createReadStream(fileName).pipe(request({
    method: 'PUT',
    url: url,
    headers: {
    'Content-Length': stats['size']
}
}, function (err, res, body) {
    console.log('success');
}));

Upvotes: 1

Supraj V
Supraj V

Reputation: 977

Your above code works only if you have custom storage(that too it should be public) and not for AWS storage.

For AWS storage access key id and the access key secret is mandatory, without these you cannot upload the files to storage

Upvotes: 2

Related Questions