如何设置使用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": [ "*" ] } } ] }
我需要的魔咒是“*”的“主”,意思是“人人”。