Generating Amazon S3 file upload Policy in Node.js
I recently (by recently, I mean two days ago) had to upload files — images to be precise — to a newly created Amazon S3 bucket. After going through a few documents online and following instructions (at least, I think I did), I had my environment (MEAN — MongoDb, Express, AngularJS and Node.js) setup for the upload.
On trying the upload, Amazon returned an error telling me the policy I was using was not the same as that which they generated. Apparently, I did something wrong somewhere so I sought to right my wrong. I found a valuable script on github (though for the life of me, I can’t seem to remember the name of the project) and here’s what I distilled it down to:
'use strict';
var AWS = require('aws-sdk'),
crypto = require('crypto'),
createS3Policy,
getExpiryTime;
getExpiryTime = function () {
var _date = new Date();
return '' + (_date.getFullYear()) + '-' + (_date.getMonth() + 1) + '-' +
(_date.getDate() + 1) + 'T' + (_date.getHours() + 3) + ':' + '00:00.000Z';
};
createS3Policy = function(contentType, subFolder, callback) {
var s3Policy = {
'expiration': getExpiryTime(),
'conditions': [
['starts-with', '$key', subFolder],
{'bucket': 'nba-agc'},
{'acl': 'public-read'},
['starts-with', '$Content-Type', contentType]
]
};
// stringify and encode the policy
var stringPolicy = JSON.stringify(s3Policy);
var base64Policy = new Buffer(stringPolicy, 'utf-8').toString('base64');
// sign the base64 encoded policy
var signature = crypto.createHmac('sha1', process.env.AWS_SECRET_KEY)
.update(new Buffer(base64Policy, 'utf-8')).digest('base64');
// build the results object
var s3Credentials = {
s3Policy: base64Policy,
s3Signature: signature,
AWSAccessKeyId: process.env.AWS_ACCESS_KEY_ID
};
// send it back
callback(s3Credentials);
};
app.get('/s3_policy', function(req, res) {
createS3Policy(req.query.mimeType, req.query.subFolder, function (creds, err) {
if (!err) {
return res.send(200, creds);
} else {
return res.send(500, err);
}
});
});
To use this, I just issue a GET request of the form: http://localhost:3000/s3_policy?subFolder=folder_name&mimeType=image/png