尝试访问上传到s3存储桶的文件时,lambda中的访问被拒绝

时间:2017-12-07 02:07:05

标签: javascript node.js amazon-s3 aws-lambda

继我在my original post

上收到的大力帮助之后

将文件上传到s3存储桶,触发一个lambda,它发送一封包含上传到s3 buket的文件信息的电子邮件

我之前已经测试过发送过电子邮件,所以我知道它有效但当我尝试包含上传数据时会触发错误

Could not fetch object data:  { AccessDenied: Access Denied
at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/services/s3.js:577:35)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)

我在网上发现了很多关于角色等政策的问题。所以我已经将lambda添加到s3事件中,并为角色添加了s3权限,例如。

https://stackoverflow.com/questions/35589641/aws-lambda-function-getting-access-denied-when-getobject-from-s3

不幸的是,这些都没有帮助。我注意到了一条评论

Then the best solution is to allow S3FullAccess, see if it works. If it does, then remove one set of access at a time from the policy and find the least privileges required for your Lambda to work. If it does not work even after giving S3FullAccess, then the problem is elsewhere

那么我该如何找到问题所在呢?

谢谢Y

   'use strict';

console.log('Loading function');

var aws = require('aws-sdk');
var ses = new aws.SES({
   region: 'us-west-2'
});
//var fileType = require('file-type');

console.log('Loading function2');

var s3 = new aws.S3({ apiVersion: '2006-03-01', accessKeyId: process.env.ACCESS_KEY, secretAccessKey: process.env.SECRET_KEY, region: process.env.LAMBDA_REGION });

console.log('Loading function3');
//var textt = "";

exports.handler = function(event, context) {
    console.log("Incoming: ", event);

  //  textt = event.Records[0].s3.object.key;
   // var output = querystring.parse(event);

   //var testData = null;

   // Get the object from the event and show its content type
   // const bucket = event.Records[0].s3.bucket.name;
   // const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    const params = {
       Bucket: 'bucket',
       Key: 'key',
    };

    s3.getObject(params, function(err, objectData) {
    if (err) {
        console.log('Could not fetch object data: ', err);
    } else {
        console.log('Data was successfully fetched from object');
        var eParams = {
            Destination: {
                ToAddresses: ["fake@fake.com"]
            },
            Message: {
                Body: {
                    Text: {
                        Data: objectData
                       // Data: textt
                    }
                },
                Subject: {
                    Data: "Email Subject!!!"
                }
            },
            Source: "fake@fake.com"
        };

        console.log('===SENDING EMAIL===');

        var email = ses.sendEmail(eParams, function(err, emailResult) {
            if (err) console.log('Error while sending email', err);
            else {
                console.log("===EMAIL SENT===");
                //console.log(objectData);
                console.log("EMAIL CODE END");
                console.log('EMAIL: ', emailResult);
                context.succeed(event);
            }
        });
    }
});

};

更新 我已经在代码中添加了注释并检查了日志......它没有超过这一行

var s3 = new aws.S3({ apiVersion: '2006-03-01', accessKeyId: process.env.ACCESS_KEY, secretAccessKey: process.env.SECRET_KEY, region: process.env.LAMBDA_REGION });

这是否与拒绝访问相关?

注意:我想要在已上传的文件的文件中

更新2

iv替换导致var s3 = new aws.S3().getObject({ Bucket: this.awsBucketName, Key: 'keyName' }, function(err, data) { if (!err) console.log(data.Body.toString()); });

问题的行

但这是TypeError: s3.getObject is not a function

还尝试了...... var s3 = new aws.S3();

这回到Could not fetch object data: { AccessDenied: Access Denied

的原始错误

1 个答案:

答案 0 :(得分:1)

首先,区域应该是S3桶区域而不是lambda区域。接下来,您需要验证您的凭据以及他们是否可以访问您已定义的S3存储桶。正如您在其中一条评论中所述,尝试将S3完全访问Amazon托管策略附加到您的IAM用户,该用户与您在Lambda中使用的凭据相关联。下一步将使用aws cli来查看您是否可以访问此存储桶。也许像 -

aws s3 ls

如上所述,你根本不应该使用凭据。由于Lambda和S3是亚马逊服务,因此您应该使用角色。只需为Lambda提供一个角色,使其可以完全访问S3,并且不使用aws IAM凭据。和

var s3 = new AWS.S3();

就足够了。