2015-11-10 17 views
1

我有一個成功將文件寫入Amazon S3存儲桶的Amazon Lambda函數。但是,默認情況下,這些文件不能公開訪問。如何在寫入時自動訪問它們?如何設置使用Amazon Lambda在S3中創建的文件的打開/下載權限?

有沒有一種方法可以更改存儲桶本身,以便所有項目都是公開可讀的(打開/下載)?

另外,我已經收集到,這可以通過IAM角色策略來完成。這是我有:

{ 
"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); 
    } 
} 
}); 

這裏是拉姆達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)); 
    }); 
} 

警告:使用當前時間,文件名後沒有投入生產。這只是生成合理唯一文件名的一種快捷方式。

回答

3

按本頁面例如:http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_examples.html 你可以這樣設置

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

一個IAM角色策略,以便你可以像arn:aws:s3:::EXAMPLE-BUCKET-NAME/public/*與文件夾結合起來,我認爲

或者你可以創建一個整體公開訪問所有文件只是爲了上傳。

或者,也許你可以從sdk使用getSignedUrl到剛剛上傳的文件,並將該網址返回給客戶端,這將使該文件可以通過該網址在給定時間內訪問(現在不記得它們多久有效的),像這樣:

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) 
    }); 
}); 
+0

我已經更改了arn,但資源仍在存儲桶中創建,沒有每個人的打開/下載權限。我想我可能還需要爲存儲桶本身創建一個單獨的策略。 –

+0

缺少的位是存儲桶策略。 –

1

除了@ mithril_knight的回答,我還需要一個桶策略(在S3控制檯設置):

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

我所需要的魔力是「校長」 「*」,意思是「每個人」。

+0

lambda&S3存儲桶是否需要位於同一區域? – ChickenWing24

相關問題