简体   繁体   English

使用aws js sdk,无需使用cognito,即可将浏览器中的大文件(> 10GB)直接从浏览器安全地分段上传到s3

[英]Secure multi-part Upload of large files(>10GB) directly from browser to s3 using aws js sdk without using cognito

Objective : to use aws js sdk and do multipart upload for large files(>10GB) directly from browser to s3 in a secure way. 目标 :使用aws js sdk并以安全的方式直接从浏览器向s3进行大文件(> 10GB)的分段上传。

Achieved : successfully able to upload files about 15GB directly from browser to s3 bucket. 实现 :成功地将大约15GB的文件直接从浏览器上传到s3存储桶。

Issue : without using amazon cognito and hard-coding the keys and secret do the same. 问题 :无需使用Amazon Cognito并对密钥和密钥进行硬编码即可。

From what we I have read form docs and what aws support team has replied that I can achieve this with STS but I did try that out check this : 根据我们阅读的表格文档以及aws支持团队的答复,我可以使用STS实现此目的,但是我确实尝试了以下方法:

from boto.s3.connection import S3Connection
from boto.sts import STSConnection
sts = STSConnection('our_key', 'our_secret')
user = sts.get_federation_token('guest_user_1')
user= sts.assume_role(role_arn='arn:aws:iam::008557872112:role/Cognito_testAuth_Role', role_session_name='Cognito_testAuth_Role_temp')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/aameer/.virtualenvs/indeedev/lib/python3.4/site-packages/boto/sts/connection.py", line 384, in assume_role
    return self.get_object('AssumeRole', params, AssumedRole, verb='POST')
  File "/home/aameer/.virtualenvs/indeedev/lib/python3.4/site-packages/boto/connection.py", line 1208, in get_object
    raise self.ResponseError(response.status, response.reason, body)
boto.exception.BotoServerError: BotoServerError: 403 Forbidden
<ErrorResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
  <Error>
    <Type>Sender</Type>
    <Code>AccessDenied</Code>
    <Message>Roles may not be assumed by root accounts.</Message>
  </Error>
  <RequestId>95e7efc9-12b3-11e6-b1e2-ffa0432dfc4b</RequestId>
</ErrorResponse>

We had read that the roles may not be assumed by root accounts but we couldn't figure out how to create these roles then. 我们已经读过,角色可能不会由root帐户承担,但我们无法弄清楚如何创建这些角色。 What we are looking for is an example which would explain the full process of: a) create a non root user to be used in the above case ie How to create temp role (whether on back-end with the help of boto or on front-end with aws js sdk) b)and then use it on front-end to achieve our objective. 我们正在寻找的示例将解释以下整个过程:a)创建在上述情况下使用的非超级用户,即如何创建临时角色(无论是在boto的帮助下还是在前端) -aws js sdk)b),然后在前端使用它来实现我们的目标。

as the docs are highly confusing on this. 因为文档对此非常困惑。

Note that : we are using django 1.7 and python3.4 with boto==1.3.1 and aws js sdk 2.2.13 to achieve this. 请注意:我们使用django 1.7和python3.4以及boto == 1.3.1和aws js sdk 2.2.13来实现此目的。

I am also sharing the js code 我也在分享js代码

//the uploads(from browser to s3) had issues with large videos(videos greater than 5GB) , the earlier implementation gist is as under:

var xhr = new XMLHttpRequest();

sign = data['signature'] //from backend
policy_json = data['policy'] //from backend

console.log('values from backend')
console.log(sign,policy_json)
var fd = new FormData();
fd.append('key', key);
fd.append('acl', 'public-read'); 
fd.append('AWSAccessKeyId', 'our_key');
fd.append('policy', policy_json);
fd.append('signature',sign);
fd.append("file",file);
xhr.upload.addEventListener("progress", $scope.uploadProgress, false);
xhr.addEventListener("load", $scope.uploadComplete, false);
xhr.addEventListener("error", uploadFailed, false);
xhr.addEventListener("abort", uploadCanceled, false);
if (window.location.href.indexOf('8000') > -1 || window.location.href.indexOf('preproduction') > -1){
   xhr.open('POST', 'https://bucket1.s3.amazonaws.com/', true); //MUST BE LAST LINE BEFORE YOU SEND 
}else{
   xhr.open('POST', 'https://bucket2.s3.amazonaws.com/', true); //MUST BE LAST LINE BEFORE YOU SEND 
}
xhr.setRequestHeader("enctype", "multipart/form-data");
//xhr.setRequestHeader("Content-Type", "undefined");
xhr.send(fd);
if (window.location.href.indexOf('8000') > -1 || window.location.href.indexOf('preproduction') > -1){
   s3URL='https://bucket1.s3.amazonaws.com/'+projectid+'/video/'+projectid+'_'+$scope.video_id+'.'+file_extension;
}else{
   s3URL='https://bucket2.s3.amazonaws.com/'+projectid+'/video/'+projectid+'_'+$scope.video_id+'.'+file_extension;
}


// to make larger files (theoritally upto 5TB) we used aws's js sdk to enable the multipart upload and new implementation which is working
//(for now whatever we threw at it(about 15GB) it uploaded it successfully so the code has improved the robustness , time and size of uploads


//But the thing is we dont want the aws key and secret to be on the front end as mentioned in the following snippet:

AWS.config.update({accessKeyId: 'our_key', secretAccessKey: 'our-secret'});

//based on the server we use the bucket
if (window.location.href.indexOf('8000') > -1 || window.location.href.indexOf('preproduction') > -1){
   AWS.config.region = 'ap-southeast-1';
   bucket_name = 'bucket1'
}else{
   AWS.config.region = 'us-west-1';
   bucket_name = 'bucket2'
}

// Upload the File
var bucket = new AWS.S3({params: {Bucket: bucket_name}});
var params = {Key: key,
            Body: file,
            acl:'public-read'}
var upload_carrier = bucket.upload(params)

upload_carrier.on('httpUploadProgress', function(evt) {
   console.log(evt.loaded *100/evt.total)
   var percentComplete = Math.round(evt.loaded * 100 / evt.total);
   document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '% Complete';
   $(".progress-bar").width(percentComplete.toString() + '%');
})

upload_carrier.send(function(err, data) {
  s3URL='https://bucket1.s3.amazonaws.com/'+projectid+'/video/'+projectid+'_'+$scope.video_id+'.'+file_extension;
  toastr.success("Video was uploaded successfully");
  _kmq.push(['record', 'Upload Finish', {'Upload Type':'Browser'}]);
  $scope.addVideo(); // adds a video on our backend
  console.log(err, data)
})

$scope.cancelUpload= function(evt) {
    toastr.error("The upload has been canceled by the user or the browser dropped the connection.");
    $scope.uploadchange=false;
    $scope.uploadbtn=true;
    $scope.isSaving=false;
    location.reload()
}

//from the docs it appears that we can use amazon incognito where we can use one of the authentication providers like fb, google amazon etc 
//to authenticate users but we don't want another level of authentication, we even tried to use amazon identity pool but it didn't work for some reason 
//and moreover it still doesn't solve the issue of not having keys and secret on front-end as we have to use something like this if we are not wrong

Set the region where your identity pool exists (us-east-1, eu-west-1)
AWS.config.region = 'us-east-1';
// Configure the credentials provider to use your identity pool
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: 'identity-pool-id',
});

// Make the call to obtain credentials
AWS.config.credentials.get(function(){
    // Credentials will be available when this function is called.
    var accessKeyId = AWS.config.credentials.accessKeyId;
    var secretAccessKey = AWS.config.credentials.secretAccessKey;
    var sessionToken = AWS.config.credentials.sessionToken;
});

//we are trying to avoid custom authentication in cognito as it feels too much of work and again cant see clear examples.
// we also know that we can use the js SDK to assume a role temporarily that would allow uploading to S3
//This would mean that we do not have to use Cognito and also do not need to hard code keys. 
//These credentials by default are live for an hour. and if they only allow access to upload to S3 there is very little risk to our other resources.

// and that is what had tried above with boto but still not luck We have been stuck on this issue for way too long,I would highly appreciate some code snippets which could help //这是上面在boto上尝试过的尝试,但是仍然没有运气我们在这个问题上停留了太久了,我非常感谢一些有助于帮助的代码片段

some of the links which we had consulted: https://docs.aws.amazon.com/cognito/latest/developerguide/developer-authenticated-identities.html \\ How to give permission to a federated user in boto to an s3 bucket? 我们咨询过的一些链接: https : //docs.aws.amazon.com/cognito/latest/developerguide/developer-authenticated-identities.html \\ 如何在boto中将联合用户的权限授予s3存储桶? \\ https://www.whitneyindustries.com/aws/2014/11/16/boto-plus-s3-plus-sts-tokens.html \\ http://boto.cloudhackers.com/en/latest/ref/sts.html \\ http://boto.cloudhackers.com/en/latest/ref/sts.html#id7 \\ http://boto.cloudhackers.com/en/latest/ref/sts.html#id19 \\ http://boto.cloudhackers.com/en/latest/ref/sts.html \\ http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html \\ http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-api.html \\ \\ https://www.whitneyindustries.com/aws/2014/11/16/boto-plus-s3-plus-sts-tokens.html \\ http://boto.cloudhackers.com/zh-CN/latest/ref/sts .html \\ http://boto.cloudhackers.com/en/latest/ref/sts.html#id7 \\ http://boto.cloudhackers.com/en/latest/ref/sts.html#id19 \\ http:/ /boto.cloudhackers.com/en/latest/ref/sts.html \\ http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html \\ http://docs.aws.amazon .com / IAM / latest / UserGuide / id_roles_use_switch-role-api.html \\

thanks, 谢谢,

 <Message>Roles may not be assumed by root accounts.</Message>

You shouldn't be using your root account credentials for anything . 您不应该将root帐户凭据用于任何用途。 You need to be using an IAM user. 您需要使用IAM用户。 Everywhere that you are using root credentials now, those need to be replaced with an IAM user's credentials. 现在,无论您在哪里使用根凭据,都需要用IAM用户的凭据替换。

See https://aws.amazon.com/iam/details/manage-users/ 参见https://aws.amazon.com/iam/details/manage-users/

See also Throw Away the Password to your AWS Account by Eric Hammond. 另请参阅Eric Hammond 将密码扔到您的AWS账户中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用适用于 JavaScript 的 AWS 开发工具包 v3 完成多部分上传到 S3 的 XML 错误 - XML error completing a multi-part upload to S3 with AWS SDK for JavaScript v3 使用 AWS-SDK-JS 使用普通 Javascript 将大文件作为流上传到 s3 - Upload large files as a stream to s3 with Plain Javascript using AWS-SDK-JS 如何在浏览器中使用 javascript sdk 在 aws s3 存储桶中上传多部分文件 - How to upload multipart files in aws s3 bucket using javascript sdk in browser 如何使用预签名的 URL 而不是凭证直接从浏览器上传到 AWS S3? - How to upload to AWS S3 directly from browser using a pre-signed URL instead of credentials? 如何使用JavaScript在AWS S3上上传大型文件和多个文件? - How to upload large and multiple files on aws s3 using javascript? S3:如何使用aws-sdk在nodejs中使用S3上传大文件 - S3 : How to upload a large file using S3 in nodejs using aws-sdk Amazon S3上传图片 - 直接从浏览器使用角度js - Amazon S3 upload image - using angular js directly from browser 直接从浏览器将图像上传到Amazon S3-使用angular js - Upload image to amazon s3 directly from browser - using angular js 使用nodejs aws sdk 将生成的pdf上传到AWS S3 - Upload pdf generated to AWS S3 using nodejs aws sdk 如何使用浏览器的 aws-sdk V3 (javascript) 跟踪上传到 S3 的进度 - How to track upload progress to S3 using aws-sdk V3 for browser (javascript)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM