Evaporate and config s3 bucket and IAM user
EvaporateJS Config AWS s3 bucket Managing Access Permissions to Your Amazon S3 Resources User Access Key In summary, create a s3 bucket, set up CORS settings and bucket policy.
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>https://*.yourdomain.com</AllowedOrigin>
<AllowedOrigin>http://*.yourdomain.com</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<ExposeHeader>ETag</ExposeHeader>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
{
"Version": "2012-10-17",
"Id": "Policy145337ddwd",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::6681765859115:user/me"
},
"Action": [
"s3:AbortMultipartUpload",
"s3:ListMultipartUploadParts",
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::mybucket/*"
}
]
}
Main codes
an example app created via '
create-reat-app' tool.
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
const Evaporate = require('evaporate');
const crypto = require('crypto');
class App extends Component {
onFileSelected(files) {
var config = {
signerUrl: 'YOURSIGNEDURL',
aws_key: 'YOURAWSKEY',
bucket: 'YOURBUCKETNAME',
cloudfront: true,
computeContentMd5: true,
cryptoMd5Method: function (data) {
return crypto.createHash('md5').update(Buffer.from(data)).digest('base64');
},
cryptoHexEncodedHash256: function (data) {
return crypto.createHash('sha256').update(Buffer.from(data)).digest('hex');
}
};
return Evaporate.create(config)
.then(function (evaporate) {
var addConfig = {
name: files[0].name,
file: files[0],
progress: function (progressValue) {
console.log('Progress', progressValue);
},
complete: function (_xhr, awsKey) {
console.log('Complete!');
},
};
var overrides = {
bucket: 'recordingsfortalkmeup'
};
evaporate.add(addConfig, overrides)
.then(function (awsObjectKey) {
console.log('File successfully uploaded to:', awsObjectKey);
},
function (reason) {
console.log('File did not upload sucessfully:', reason);
});
});
}
render() {
return (
<div className="App">
<input type='file' onChange={(e) => this.onFileSelected(e.target.files)
}/>
</div>
);
}
}
export default App;
Signer URL
Create a lambda function to do the signature process.
Signing AWS Requests with Signature Version 4
'use strict';
console.log('Loading upload signature function');
const crypto = require("crypto");
function hmac(key, string){
const hmac = crypto.createHmac('sha256', key);
hmac.end(string);
return hmac.read();
}
exports.handler = function(event, context, callback) {
console.log(JSON.stringify(event));
let to_sign = event.queryStringParameters.to_sign;
let timestamp = event.queryStringParameters.datetime.substr(0, 8);
console.log(to_sign);
console.log('date:', timestamp);
console.log('aws secret key:', process.env.AWS_SECRET);
console.log('region:', process.env.AWS_REGION);
console.log('service:s3');
let dateKey = hmac('AWS4' + process.env.AWS_SECRET, timestamp);
let dateRegionKey = hmac(dateKey, process.env.AWS_REGION);
let dateRegionServiceKey = hmac(dateRegionKey, 's3');
let signingKey = hmac(dateRegionServiceKey, 'aws4_request');
let signature = hmac(signingKey, to_sign).toString('hex');
console.log('Created signature "' + signature + '" from ' + to_sign);
var response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin" : "*",
"Content-Type": "text/html"
},
body: signature
};
callback(null, response);
};
Build an rest API bind with this Lambda function and deploy it, then you will get an invoke url which will be your signer url.
Build an API Gateway API with Lambda Integration
Test
Everything is ok, you will find new uploaded file in your s3 bucket.