如何设置使用Amazon Lambda在S3中创build的文件的打开/下载权限?

我有一个成功将文件写入Amazon S3存储桶的Amazon Lambda函数。 但是,默认情况下,这些文件不能公开访问。 如何在写入时自动访问它们?

有没有办法改变桶本身,使所有的项目是公开可读的(打开/下载)?

或者,我已经收集到这可以通过IAMangular色策略来完成。 这是我的:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:*" }, { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::*" ] } ] } 

我认为这是“资源”,需要改变,但我不知道如何。

为了完整性(如果有其他人需要做类似的事情,并且涉及到Lambda文档),这里是我在客户端的ajax调用(我正在向S3写一个图像,并且需要返回文件名):

 $.ajax({ url: 'https://mylambdafunctionurl/', type: 'POST', crossDomain: true, contentType: 'application/json', data: JSON.stringify(data), dataType: 'json', success: function(data) { var path = "https://myregion.amazonaws.com/mybucket/"; var filename = JSON.parse(data).filename; document.getElementById('finalimage').innerHTML = "<a href='"+path+filename+"'>Your image</a>"; }, error: function(xhr, ajaxOptions, thrownError) { if (xhr.status == 200) { console.log(ajaxOptions); } else { console.log("Error: "); console.log(xhr.status); console.log(thrownError); } } }); 

这里是Lambda POST函数(nodejs):

 var AWS = require('aws-sdk'); var s3 = new AWS.S3(); exports.handler = function(event,context) { var s3 = new AWS.S3(); var nowtime = new Date(); var bodycontent = event.image; mykey = nowtime.getTime() + '.png'; var param = {Bucket: 'mybucket', Key: mykey, Body: bodycontent}; var successdata = {filename:mykey}; s3.upload(param, function(e,data) { if (e) { console.log(e,e.stack); } else { console.log(event); } context.done(null,JSON.stringify(successdata)); }); } 

警告:使用当前的文件名时间不是生产准备。 这只是一个快速的方法来产生一个合理的唯一的文件名。

按照此页面示例: http : //docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_examples.html您可以设置IAMangular色策略

 ... { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject" ], "Resource": "arn:aws:s3:::EXAMPLE-BUCKET-NAME/*" } ... 

所以你可以把它和一个像arn:aws:s3:::EXAMPLE-BUCKET-NAME/public/*这样的文件夹结合起来arn:aws:s3:::EXAMPLE-BUCKET-NAME/public/*我认为

或者您可以创build一个公共访问所有文件的整个桶,只是为了上传。

或者,也许你可以使用从sdk的getSignedUrl到刚刚上传的文件,并返回该url到客户端,这将使文件访问通过该url给定的时间(不记得现在多久,他们是有效的),就像这个:

 s3.putObject({ Bucket: bucket, Key: key, Body: fs.createReadStream(path), ContentType: contentType, }, function(err, data) { if (err) return callback(err, null); s3.getSignedUrl('getObject', { Bucket: 'mybucket', Key: 'mypublicfiles/myfile.txt' }, function(err, url) { if (err) return callback(err, null) else return callback(null, url) }); }); 

除了@ mithril_knight的回答之外,我还需要一个桶策略(在S3控制台中设置):

 { "Id": "Policyxxxxxxxxxx", "Version": "2012-10-17", "Statement": [ { "Sid": "Stmtxxxxxxxxxx", "Action": [ "s3:GetObject" ], "Effect": "Allow", "Resource": "arn:aws:s3:::mybucket/*", "Principal": { "AWS": [ "*" ] } } ] } 

我需要的魔咒是“*”的“主”,意思是“人人”。