【问题标题】:Creating a AWS Cognito PreSignup Lambda in DotNet在 DotNet 中创建 AWS Cognito PreSignup Lambda
【发布时间】:2017-10-24 03:08:31
【问题描述】:

使用 .Net Core 1.0 Lambda 我希望能够创建一个 Lambda 函数来处理来自 AWS Cognito 用户池的 PreSignUp 触发器。

using Amazon.Lambda.Core;

[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]

public class PreSignUp_SignUp
{
  public string userPoolId { get; set; }
  public const string EmailKey = "email";
  public const string PhoneNumber = "phone_number";
  public Dictionary<string,string> userAttributes { get; set; }
  public Dictionary<string, string> validationData { get; set; }
}

public class PreSignup_SignUpResponse
{
  public bool autoConfirmUser { get; set; }
}

public class Function
{
  public PreSignup_SignUpResponse FunctionHandler(PreSignUp_SignUp input, ILambdaContext context)
  {
      return new PreSignup_SignUpResponse { autoConfirmUser = true };
  }
}

虽然请求成功并在调用 Lambda 时返回响应,但示例请求如下:

{
  "datasetName": "datasetName",
  "eventType": "SyncTrigger",
  "region": "us-east-1",
  "identityId": "identityId",
  "datasetRecords": {
    "SampleKey2": {
      "newValue": "newValue2",
      "oldValue": "oldValue2",
      "op": "replace"
    },
    "SampleKey1": {
      "newValue": "newValue1",
      "oldValue": "oldValue1",
      "op": "replace"
    }
  },
  "identityPoolId": "identityPoolId",
  "version": 2
}

通过 .Net AmazonCognitoIdentityProviderClient 执行实际注册时,我收到错误消息:

Amazon.CognitoIdentityProvider.Model.InvalidLambdaResponseException : 无法识别的 lambda 输出

我猜这意味着我没有得到正确的响应(甚至可能是请求)的形状。

是否有人提供适用于 AWS Cognito 中 PreSignUp 触发器的 .Net Lambda 函数示例?

【问题讨论】:

    标签: c# amazon-web-services .net-core aws-lambda aws-cognito


    【解决方案1】:

    认知触发器请求/响应必须包含认知触发器文档中指定的整个有效负载:

    http://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html

    在诊断此问题时,我发现最好的起点是创建一个函数处理程序,该处理程序接受一个 JObject,然后记录并返回相同的对象,例如

    public JObject FunctionHandler(JObject input, ILambdaContext context)
    {
        context.Logger.LogLine("Input was: " + input);
        return input;
    }
    

    这会在 cloudwatch 日志中捕获有效负载,然后帮助引导您实现所需的强类型结构化。

    在我的 PreSignUp 案例中,我最终创建了以下类型来创建一个简单的函数,该函数可以自动验证所有提供的凭据。

    public abstract class AbstractTriggerRequest
    {
        [JsonProperty("userAttributes")]
        public Dictionary<string, string> UserAttributes { get; set; }
    }
    
    public abstract class AbstractTriggerResponse
    {
    }
    
    public class TriggerCallerContext
    {
        [JsonProperty("awsSdkVersion")]
        public string AwsSdkVersion { get; set; }
        [JsonProperty("clientId")]
        public string ClientId { get; set; }
    }
    
    public abstract class AbstractTriggerBase<TRequest, TResponse>
        where TRequest: AbstractTriggerRequest
        where TResponse: AbstractTriggerResponse
    {
        [JsonProperty("version")]
        public int Version { get; set; }
        [JsonProperty("triggerSource")]
        public string TriggerSource { get; set; }
        [JsonProperty("region")]
        public string Region { get; set; }
        [JsonProperty("userPoolId")]
        public string UserPoolId { get; set; }  
        [JsonProperty("callerContext")]
        public TriggerCallerContext CallerContext { get; set; }
        [JsonProperty("request")]
        public TRequest Request { get; set; }
        [JsonProperty("response")]
        public TResponse Response { get; set; }
        [JsonProperty("userName", NullValueHandling = NullValueHandling.Ignore)]
        public string UserName { get; set; }
    }
    
    public class PreSignUpSignUpRequest : AbstractTriggerRequest
    {
        [JsonProperty("validationData")]
        public Dictionary<string,string> ValidationData { get; set; }
    }
    

    然后,Lambda 函数以以下签名结束:

    public class Function
    {
        public PreSignUp_SignUp FunctionHandler(PreSignUp_SignUp input, ILambdaContext context)
        {
            context.Logger.LogLine("Auto-confirming everything!");
    
            input.Response = new PreSignUpSignUpResponse {
                AutoConfirmUser = true,
                // you can only auto-verify email or phone if it's present in the user attributes
                AutoVerifyEmail = input.Request.UserAttributes.ContainsKey("email"),
                AutoVerifyPhone = input.Request.UserAttributes.ContainsKey("phone_number") 
            };
    
            return input;
        }
    }
    

    希望这可以帮助其他在为 Cognito 编写 Lambda 触发器时遇到问题的人。

    【讨论】:

    • 这是一个很好的答案,但也请查看 DaddyCoder 对 .netcore 3.1 应用程序语法更新的响应,因为您可能会使用新的 JSON 序列化程序
    【解决方案2】:

    除非您仍然使用旧的、性能较低的 Amazon.Lambda.Serialization.Json.JsonSerializer,否则之前的两个响应现在不准确。这个旧的序列化程序使用Newtonsoft.Json,而新的Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer 实现了最近的System.Text.Json

    因此,JObject 参数不再适用,而应替换为 JsonElement。如果你尝试将JObject 与这个新的序列化程序一起使用,你会得到一个错误,因为序列化程序不知道如何处理这个对象。

    您应该阅读this 以更好地了解它的工作原理,但您可以使用GetProperty("[insert property name here]") 访问JsonElement 的属性。

    例如:

    public async Task<JsonElement> FunctionHandler(JsonElement input, ILambdaContext context)
    {
        var request = input.GetProperty("request");
        var userAttributes = request.GetProperty("userAttributes");
        string email = userAttributes.GetProperty("email").GetString();
    
        return input;
    }
    

    这样,您无需构建整个类来容纳所需的请求和响应参数,只需获取和设置您需要的属性即可。

    【讨论】:

    • 这是正确的。 JsonElement 类也可以很好地记录日志,因此按照 Bittercoder 推荐的记录输入的起点,您仍然可以使用以下语法:context.Logger.LogLine("Input was: " + input); 查看 Cloudwatch 日志中的请求负载。
    【解决方案3】:

    这里已经有另一个很好的答案了。不过我不是 .NET 开发专家,所以这个解决方案对我来说更有意义。

    class AutoVerifyEmail
    {
        public AutoVerifyEmail() { }
    
        public JObject AutoVerifyEmailPreSignup(JObject input, ILambdaContext context)
        {
            //Console.Write(input); //Print Input
    
            input["response"]["autoVerifyEmail"] = true;
            input["response"]["autoConfirmUser"] = true;
    
            return input;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-10-28
      • 2021-11-05
      • 2021-02-24
      • 2022-07-21
      • 1970-01-01
      • 1970-01-01
      • 2021-11-28
      • 2021-12-30
      • 2021-04-21
      相关资源
      最近更新 更多