I have tried to upload directly to Amazon S3 bucket using client side SDK. My code is based on this post : http://www.cheynewallace.com/uploading-to-s3-with-angularjs/. I can do the upload and view the files using S3 console.However when I try to execute putObject from Client side I am getting 403 error. Pls help me figure out where am I going wrong.
CORS settings:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<ExposeHeader>x-amz-server-side-encryption</ExposeHeader>
<ExposeHeader>x-amz-request-id</ExposeHeader>
<ExposeHeader>x-amz-id-2</ExposeHeader>
<AllowedHeader>*</AllowedHeader>
<AllowedHeader>x-amz-acl</AllowedHeader>
</CORSRule>
</CORSConfiguration>
2. Bucket Policy
{
"Version": "2012-10-17",
"Id": "Policy1460109621028",
"Statement": [
{
"Sid": "Stmt1460109523730",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:PutObjectAcl",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::zxcvbucketdemo123/*",
"arn:aws:s3:::zxcvbucketdemo123"
]
}
]
}
3. IAM policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
4. Controller.js
app.controller('DemoCtrl123', ['$scope', function($scope) {
$scope.sizeLimit = 10585760; // 10MB in Bytes
$scope.uploadProgress = 0;
$scope.creds={} ;
$scope.creds.bucket='zxcvbucketdemo123';
$scope.creds.access_key='xxxxxxxxxxxxxx';
$scope.creds.secret_key='yyyyyyyyyyyyyyyyyyyyy';
$scope.upload = function() {
console.log("inside amazon s3 controller upload function....");
AWS.config.update({ accessKeyId: $scope.creds.access_key, secretAccessKey: $scope.creds.secret_key });
AWS.config.region = 'us-west-2';
var bucket = new AWS.S3({ params: { Bucket: $scope.creds.bucket } });
console.log($scope.creds.bucket);
console.log(bucket);
if($scope.file) {
// Perform File Size Check First
/*var fileSize = Math.round(parseInt($scope.file.size));
console.log(filesize);
if (fileSize > $scope.sizeLimit) {
toastr.error('Sorry, your attachment is too big. <br/> Maximum ' + $scope.fileSizeLabel() + ' file attachment allowed','File Too Large');
return false;
}*/
// Prepend Unique String To Prevent Overwrites
var uniqueFileName = $scope.uniqueString() + '-' + $scope.file.name;
// var params = { Key: uniqueFileName, ContentType: $scope.file.type, Body: $scope.file, ServerSideEncryption: 'AES256' };
var params = { Key: uniqueFileName, ContentType: $scope.file.type, Body: $scope.file};
console.log(params);
console.log(uniqueFileName);
console.log($scope.file.type);
console.log($scope.file);
bucket.putObject(params, function(err, data) {
if(err) {
console.log("inside amazon s3 controller putobject error....");
toastr.error(err.message,err.code);
return false;
}
else {
// Upload Successfully Finished
console.log("inside amazon s3 controller upload succesful....");
toastr.success('File Uploaded Successfully', 'Done');
// Reset The Progress Bar
setTimeout(function() {
$scope.uploadProgress = 0;
$scope.$digest();
}, 4000);
}
})
.on('httpUploadProgress',function(progress) {
$scope.uploadProgress = Math.round(progress.loaded / progress.total * 100);
$scope.$digest();
});
}
else {
// No File Selected
toastr.error('Please select a file to upload');
}
}
$scope.fileSizeLabel = function() {
// Convert Bytes To MB
return Math.round($scope.sizeLimit / 1024 / 1024) + 'MB';
};
$scope.uniqueString = function() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 8; i++ ) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
}]);
For me adding:
<ExposeHeader>ETag</ExposeHeader>
inside the <CORSRule>
solved this exact problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With