使用lambda配置为触发器

时间:2017-03-21 17:35:36

标签: javascript amazon-web-services aws-lambda aws-sdk aws-cognito

我正在尝试使用JavaScript SDK以编程方式从脚本创建Cognito用户池。

我已经成功创建了用户池,并通过在我的配置中指定相关lambdas的arn来定义预注册和后确认触发器。 (根据docs

我的脚本如下所示:

const aws = require('aws-sdk');
const awsConfig = require('../config/config');

aws.config.update({ region: awsConfig.REGION });

const provider = new aws.CognitoIdentityServiceProvider();


// user provided args
const stage = process.argv[2];

if (!stage) {
  process.stdout.write('Please provide stage as argument\n');
  process.exit(1);
}


// generate arns for pre and post cognito triggers
const getArn = (lambdaName) => {
  return `arn:aws:lambda:${awsConfig.REGION}:${awsConfig.AWS_ACCOUNT_ID}` +
         `:function:my-project-name-${stage}-${lambdaName}`;
};

const preSignUp = getArn('preSignUp');
const postConfirmation = getArn('postConfirmation');


const userPoolConfig = {
  PoolName: `mypool-${stage}`,
  AutoVerifiedAttributes: ['email'],
  Schema: [
    {
      "StringAttributeConstraints": {
        "MaxLength": "2048",
        "MinLength": "0"
      },
      "Mutable": true,
      "Required": true,
      "AttributeDataType": "String",
      "Name": "email",
      "DeveloperOnlyAttribute": false
    }
  ],
  LambdaConfig: {
    PostConfirmation: postConfirmation,
    PreSignUp: preSignUp
  }
};


const callback = (err, resp) => {
  if (err) {
    process.stdout.write(`${err}\n`);
  } else {
    process.stdout.write(resp.UserPool.Id);
  }
};


provider.createUserPool(userPoolConfig, callback);

当我运行此脚本时,它成功创建了用户池,当我在控制台中检查它时,触发器设置正确。

当我尝试在我的用户池上注册用户时,我收到错误:

AccessDeniedException { code: 'UnexpectedLambdaException', ... }

如果我进入控制台并手动设置触发器,它就可以正常工作。

此错误已被报告 - 但我看不到确认,也没有解决方案:

https://github.com/aws/aws-cli/issues/2256

迫切无法修复或找到解决方法。

3 个答案:

答案 0 :(得分:4)

如果您需要在serverless.yml文件中添加权限,那么这对我们有用。将其添加到“资源”部分:

UserPoolLambdaInvokePermission:
  Type: AWS::Lambda::Permission
  Properties:
    Action: lambda:invokeFunction
    Principal: cognito-idp.amazonaws.com
    FunctionName: <function-name>
    SourceArn: arn:aws:cognito-idp:<your region>:<your account>:userpool/*

这使所有用户池都可以调用您的特定功能。

您可以通过查看.serverless / serverless-state.json来获得要使用的函数名称,然后在您的lambda上看到FunctionName属性。

答案 1 :(得分:3)

如果您在云编队中设置了用户池和lambda触发器,则需要为用户池添加适当的权限以调用lambda函数。

您必须将这样的内容添加到您的云形成模板中。

"UserPoolPreSignupLambdaInvokePermission"    : {
    "Type" : "AWS::Lambda::Permission",
    "Properties" : {
        "Action" : "lambda:invokeFunction",
        "Principal" : "cognito-idp.amazonaws.com",
        "FunctionName" :{ "Ref" : "AutoVerifyEmailPreSignupLambdaFunction" },
        "SourceArn"    : {
            "Fn::Sub" : "arn:aws:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/${UserPool}"
        }
    }
}

答案 2 :(得分:1)

我设法解决了这个问题。问题是lambda没有与cognito交互的正确权限。

我发现这段信息隐藏在here

之外

因此,在创建用户池的回调函数中,我附加了正确的权限,如下所示:

$list = 'test'
$tmpFiltre2 = 'c:\test.csv'
Import-Csv $tmpFiltre2 -Delimiter "," | Where-Object {
    $_.msg -and $list -like $_.msg
} | group msg -NoElement

请参阅有关通过JavaScript SDK here

添加权限的文档