How to set Open/Download permissions on a file created in S3 with Amazon Lambda?

╄→гoц情女王★ 提交于 2019-12-24 16:03:06

问题


I have an Amazon Lambda function that successfully writes files to an Amazon S3 bucket. However, by default these files are not publicly accessible. How do I make them automatically accessible when they are written?

Is there a way to change the bucket itself so that all items are publicly readable (open/download)?

Alternatively, I've gleaned that this can be done with the IAM role policy. This is what I have:

{
"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:::*"
  ]
}
]
}

I think it's the "Resource" that needs to be changed, but I'm not sure how.

For completeness (in case anyone else needs to do something similar and is wading into the morass that is the Lambda documentation), here's my ajax call on the clientside (I'm writing an image to S3 and need the filename back):

$.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);
    }
}
});

And here is the Lambda POST function (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));
    });
}

Caveat: using the current time for the filename is not production ready. It was just a quick way to produce a reasonably unique filename.


回答1:


as per this page example: http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_examples.html you could set a IAM role policy like this

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

So you could combine it with a folder like arn:aws:s3:::EXAMPLE-BUCKET-NAME/public/* I think

Or you could create a whole bucket with public access to all files just for uploading.

Or maybe you could use getSignedUrl from the sdk to the just uploaded file and return that url to the client, that will make the file accessible through that url for a given time(don't remember right now how long they are valid), like this:

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



回答2:


In addition to @mithril_knight's answer, I also needed a bucket policy (set in the S3 console):

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

The mojo I needed was the "Principal" of "*", which means "Everyone".



来源:https://stackoverflow.com/questions/33631229/how-to-set-open-download-permissions-on-a-file-created-in-s3-with-amazon-lambda

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!