在完成 Amazon Cognito 用户身份验证后,通过 Amazon SDK 使用 Lambda 函数写入自定义活动数据 - Amazon Lambda
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

在完成 Amazon Cognito 用户身份验证后,通过 Amazon SDK 使用 Lambda 函数写入自定义活动数据

以下代码示例显示了在完成 Amazon Cognito 用户身份验证后如何使用 Lambda 函数写入自定义活动数据。

  • 使用管理员功能将用户添加到用户池。

  • 配置用户池以调用 PostAuthentication 触发器的 Lambda 函数。

  • 将新用户登录到 Amazon Cognito 控制台。

  • Lambda 函数会将自定义信息写入 CloudWatch Logs 和 DynamoDB 表。

  • 从 DynamoDB 表获取并显示自定义数据,然后清理资源。

Go
适用于 Go V2 的 SDK
注意

查看 GitHub,了解更多信息。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

在命令提示符中运行交互式场景。

// ActivityLog separates the steps of this scenario into individual functions so that // they are simpler to read and understand. type ActivityLog struct { helper IScenarioHelper questioner demotools.IQuestioner resources Resources cognitoActor *actions.CognitoActions } // NewActivityLog constructs a new activity log runner. func NewActivityLog(sdkConfig aws.Config, questioner demotools.IQuestioner, helper IScenarioHelper) ActivityLog { scenario := ActivityLog{ helper: helper, questioner: questioner, resources: Resources{}, cognitoActor: &actions.CognitoActions{CognitoClient: cognitoidentityprovider.NewFromConfig(sdkConfig)}, } scenario.resources.init(scenario.cognitoActor, questioner) return scenario } // AddUserToPool selects a user from the known users table and uses administrator credentials to add the user to the user pool. func (runner *ActivityLog) AddUserToPool(userPoolId string, tableName string) (string, string) { log.Println("To facilitate this example, let's add a user to the user pool using administrator privileges.") users, err := runner.helper.GetKnownUsers(tableName) if err != nil { panic(err) } user := users.Users[0] log.Printf("Adding known user %v to the user pool.\n", user.UserName) err = runner.cognitoActor.AdminCreateUser(userPoolId, user.UserName, user.UserEmail) if err != nil { panic(err) } pwSet := false password := runner.questioner.AskPassword("\nEnter a password that has at least eight characters, uppercase, lowercase, numbers and symbols.\n"+ "(the password will not display as you type):", 8) for !pwSet { log.Printf("\nSetting password for user '%v'.\n", user.UserName) err = runner.cognitoActor.AdminSetUserPassword(userPoolId, user.UserName, password) if err != nil { var invalidPassword *types.InvalidPasswordException if errors.As(err, &invalidPassword) { password = runner.questioner.AskPassword("\nEnter another password:", 8) } else { panic(err) } } else { pwSet = true } } log.Println(strings.Repeat("-", 88)) return user.UserName, password } // AddActivityLogTrigger adds a Lambda handler as an invocation target for the PostAuthentication trigger. func (runner *ActivityLog) AddActivityLogTrigger(userPoolId string, activityLogArn string) { log.Println("Let's add a Lambda function to handle the PostAuthentication trigger from Cognito.\n" + "This trigger happens after a user is authenticated, and lets your function take action, such as logging\n" + "the outcome.") err := runner.cognitoActor.UpdateTriggers( userPoolId, actions.TriggerInfo{Trigger: actions.PostAuthentication, HandlerArn: aws.String(activityLogArn)}) if err != nil { panic(err) } runner.resources.triggers = append(runner.resources.triggers, actions.PostAuthentication) log.Printf("Lambda function %v added to user pool %v to handle PostAuthentication Cognito trigger.\n", activityLogArn, userPoolId) log.Println(strings.Repeat("-", 88)) } // SignInUser signs in as the specified user. func (runner *ActivityLog) SignInUser(clientId string, userName string, password string) { log.Printf("Now we'll sign in user %v and check the results in the logs and the DynamoDB table.", userName) runner.questioner.Ask("Press Enter when you're ready.") authResult, err := runner.cognitoActor.SignIn(clientId, userName, password) if err != nil { panic(err) } log.Println("Sign in successful.", "The PostAuthentication Lambda handler writes custom information to CloudWatch Logs.") runner.resources.userAccessTokens = append(runner.resources.userAccessTokens, *authResult.AccessToken) } // GetKnownUserLastLogin gets the login info for a user from the Amazon DynamoDB table and displays it. func (runner *ActivityLog) GetKnownUserLastLogin(tableName string, userName string) { log.Println("The PostAuthentication handler also writes login data to the DynamoDB table.") runner.questioner.Ask("Press Enter when you're ready to continue.") users, err := runner.helper.GetKnownUsers(tableName) if err != nil { panic(err) } for _, user := range users.Users { if user.UserName == userName { log.Println("The last login info for the user in the known users table is:") log.Printf("\t%+v", *user.LastLogin) } } log.Println(strings.Repeat("-", 88)) } // Run runs the scenario. func (runner *ActivityLog) Run(stackName string) { defer func() { if r := recover(); r != nil { log.Println("Something went wrong with the demo.") runner.resources.Cleanup() } }() log.Println(strings.Repeat("-", 88)) log.Printf("Welcome\n") log.Println(strings.Repeat("-", 88)) stackOutputs, err := runner.helper.GetStackOutputs(stackName) if err != nil { panic(err) } runner.resources.userPoolId = stackOutputs["UserPoolId"] runner.helper.PopulateUserTable(stackOutputs["TableName"]) userName, password := runner.AddUserToPool(stackOutputs["UserPoolId"], stackOutputs["TableName"]) runner.AddActivityLogTrigger(stackOutputs["UserPoolId"], stackOutputs["ActivityLogFunctionArn"]) runner.SignInUser(stackOutputs["UserPoolClientId"], userName, password) runner.helper.ListRecentLogEvents(stackOutputs["ActivityLogFunction"]) runner.GetKnownUserLastLogin(stackOutputs["TableName"], userName) runner.resources.Cleanup() log.Println(strings.Repeat("-", 88)) log.Println("Thanks for watching!") log.Println(strings.Repeat("-", 88)) }

使用 Lambda 函数处理 PostAuthentication 触发器。

const TABLE_NAME = "TABLE_NAME" // LoginInfo defines structured login data that can be marshalled to a DynamoDB format. type LoginInfo struct { UserPoolId string `dynamodbav:"UserPoolId"` ClientId string `dynamodbav:"ClientId"` Time string `dynamodbav:"Time"` } // UserInfo defines structured user data that can be marshalled to a DynamoDB format. type UserInfo struct { UserName string `dynamodbav:"UserName"` UserEmail string `dynamodbav:"UserEmail"` LastLogin LoginInfo `dynamodbav:"LastLogin"` } // GetKey marshals the user email value to a DynamoDB key format. func (user UserInfo) GetKey() map[string]dynamodbtypes.AttributeValue { userEmail, err := attributevalue.Marshal(user.UserEmail) if err != nil { panic(err) } return map[string]dynamodbtypes.AttributeValue{"UserEmail": userEmail} } type handler struct { dynamoClient *dynamodb.Client } // HandleRequest handles the PostAuthentication event by writing custom data to the logs and // to an Amazon DynamoDB table. func (h *handler) HandleRequest(ctx context.Context, event events.CognitoEventUserPoolsPostAuthentication) (events.CognitoEventUserPoolsPostAuthentication, error) { log.Printf("Received post authentication trigger from %v for user '%v'", event.TriggerSource, event.UserName) tableName := os.Getenv(TABLE_NAME) user := UserInfo{ UserName: event.UserName, UserEmail: event.Request.UserAttributes["email"], LastLogin: LoginInfo{ UserPoolId: event.UserPoolID, ClientId: event.CallerContext.ClientID, Time: time.Now().Format(time.UnixDate), }, } // Write to CloudWatch Logs. fmt.Printf("%#v", user) // Also write to an external system. This examples uses DynamoDB to demonstrate. userMap, err := attributevalue.MarshalMap(user) if err != nil { log.Printf("Couldn't marshal to DynamoDB map. Here's why: %v\n", err) } else if len(userMap) == 0 { log.Printf("User info marshaled to an empty map.") } else { _, err := h.dynamoClient.PutItem(ctx, &dynamodb.PutItemInput{ Item: userMap, TableName: aws.String(tableName), }) if err != nil { log.Printf("Couldn't write to DynamoDB. Here's why: %v\n", err) } else { log.Printf("Wrote user info to DynamoDB table %v.\n", tableName) } } return event, nil } func main() { sdkConfig, err := config.LoadDefaultConfig(context.TODO()) if err != nil { log.Panicln(err) } h := handler{ dynamoClient: dynamodb.NewFromConfig(sdkConfig), } lambda.Start(h.HandleRequest) }

创建一个执行常见任务的结构。

// IScenarioHelper defines common functions used by the workflows in this example. type IScenarioHelper interface { Pause(secs int) GetStackOutputs(stackName string) (actions.StackOutputs, error) PopulateUserTable(tableName string) GetKnownUsers(tableName string) (actions.UserList, error) AddKnownUser(tableName string, user actions.User) ListRecentLogEvents(functionName string) } // ScenarioHelper contains AWS wrapper structs used by the workflows in this example. type ScenarioHelper struct { questioner demotools.IQuestioner dynamoActor *actions.DynamoActions cfnActor *actions.CloudFormationActions cwlActor *actions.CloudWatchLogsActions isTestRun bool } // NewScenarioHelper constructs a new scenario helper. func NewScenarioHelper(sdkConfig aws.Config, questioner demotools.IQuestioner) ScenarioHelper { scenario := ScenarioHelper{ questioner: questioner, dynamoActor: &actions.DynamoActions{DynamoClient: dynamodb.NewFromConfig(sdkConfig)}, cfnActor: &actions.CloudFormationActions{CfnClient: cloudformation.NewFromConfig(sdkConfig)}, cwlActor: &actions.CloudWatchLogsActions{CwlClient: cloudwatchlogs.NewFromConfig(sdkConfig)}, } return scenario } // Pause waits for the specified number of seconds. func (helper ScenarioHelper) Pause(secs int) { if !helper.isTestRun { time.Sleep(time.Duration(secs) * time.Second) } } // GetStackOutputs gets the outputs from the specified CloudFormation stack in a structured format. func (helper ScenarioHelper) GetStackOutputs(stackName string) (actions.StackOutputs, error) { return helper.cfnActor.GetOutputs(stackName), nil } // PopulateUserTable fills the known user table with example data. func (helper ScenarioHelper) PopulateUserTable(tableName string) { log.Printf("First, let's add some users to the DynamoDB %v table we'll use for this example.\n", tableName) err := helper.dynamoActor.PopulateTable(tableName) if err != nil { panic(err) } } // GetKnownUsers gets the users from the known users table in a structured format. func (helper ScenarioHelper) GetKnownUsers(tableName string) (actions.UserList, error) { knownUsers, err := helper.dynamoActor.Scan(tableName) if err != nil { log.Printf("Couldn't get known users from table %v. Here's why: %v\n", tableName, err) } return knownUsers, err } // AddKnownUser adds a user to the known users table. func (helper ScenarioHelper) AddKnownUser(tableName string, user actions.User) { log.Printf("Adding user '%v' with email '%v' to the DynamoDB known users table...\n", user.UserName, user.UserEmail) err := helper.dynamoActor.AddUser(tableName, user) if err != nil { panic(err) } } // ListRecentLogEvents gets the most recent log stream and events for the specified Lambda function and displays them. func (helper ScenarioHelper) ListRecentLogEvents(functionName string) { log.Println("Waiting a few seconds to let Lambda write to CloudWatch Logs...") helper.Pause(10) log.Println("Okay, let's check the logs to find what's happened recently with your Lambda function.") logStream, err := helper.cwlActor.GetLatestLogStream(functionName) if err != nil { panic(err) } log.Printf("Getting some recent events from log stream %v\n", *logStream.LogStreamName) events, err := helper.cwlActor.GetLogEvents(functionName, *logStream.LogStreamName, 10) if err != nil { panic(err) } for _, event := range events { log.Printf("\t%v", *event.Message) } log.Println(strings.Repeat("-", 88)) }

创建一个封装 Amazon Cognito 操作的结构。

type CognitoActions struct { CognitoClient *cognitoidentityprovider.Client } // Trigger and TriggerInfo define typed data for updating an Amazon Cognito trigger. type Trigger int const ( PreSignUp Trigger = iota UserMigration PostAuthentication ) type TriggerInfo struct { Trigger Trigger HandlerArn *string } // UpdateTriggers adds or removes Lambda triggers for a user pool. When a trigger is specified with a `nil` value, // it is removed from the user pool. func (actor CognitoActions) UpdateTriggers(userPoolId string, triggers ...TriggerInfo) error { output, err := actor.CognitoClient.DescribeUserPool(context.TODO(), &cognitoidentityprovider.DescribeUserPoolInput{ UserPoolId: aws.String(userPoolId), }) if err != nil { log.Printf("Couldn't get info about user pool %v. Here's why: %v\n", userPoolId, err) return err } lambdaConfig := output.UserPool.LambdaConfig for _, trigger := range triggers { switch trigger.Trigger { case PreSignUp: lambdaConfig.PreSignUp = trigger.HandlerArn case UserMigration: lambdaConfig.UserMigration = trigger.HandlerArn case PostAuthentication: lambdaConfig.PostAuthentication = trigger.HandlerArn } } _, err = actor.CognitoClient.UpdateUserPool(context.TODO(), &cognitoidentityprovider.UpdateUserPoolInput{ UserPoolId: aws.String(userPoolId), LambdaConfig: lambdaConfig, }) if err != nil { log.Printf("Couldn't update user pool %v. Here's why: %v\n", userPoolId, err) } return err } // SignUp signs up a user with Amazon Cognito. func (actor CognitoActions) SignUp(clientId string, userName string, password string, userEmail string) (bool, error) { confirmed := false output, err := actor.CognitoClient.SignUp(context.TODO(), &cognitoidentityprovider.SignUpInput{ ClientId: aws.String(clientId), Password: aws.String(password), Username: aws.String(userName), UserAttributes: []types.AttributeType{ {Name: aws.String("email"), Value: aws.String(userEmail)}, }, }) if err != nil { var invalidPassword *types.InvalidPasswordException if errors.As(err, &invalidPassword) { log.Println(*invalidPassword.Message) } else { log.Printf("Couldn't sign up user %v. Here's why: %v\n", userName, err) } } else { confirmed = output.UserConfirmed } return confirmed, err } // SignIn signs in a user to Amazon Cognito using a username and password authentication flow. func (actor CognitoActions) SignIn(clientId string, userName string, password string) (*types.AuthenticationResultType, error) { var authResult *types.AuthenticationResultType output, err := actor.CognitoClient.InitiateAuth(context.TODO(), &cognitoidentityprovider.InitiateAuthInput{ AuthFlow: "USER_PASSWORD_AUTH", ClientId: aws.String(clientId), AuthParameters: map[string]string{"USERNAME": userName, "PASSWORD": password}, }) if err != nil { var resetRequired *types.PasswordResetRequiredException if errors.As(err, &resetRequired) { log.Println(*resetRequired.Message) } else { log.Printf("Couldn't sign in user %v. Here's why: %v\n", userName, err) } } else { authResult = output.AuthenticationResult } return authResult, err } // ForgotPassword starts a password recovery flow for a user. This flow typically sends a confirmation code // to the user's configured notification destination, such as email. func (actor CognitoActions) ForgotPassword(clientId string, userName string) (*types.CodeDeliveryDetailsType, error) { output, err := actor.CognitoClient.ForgotPassword(context.TODO(), &cognitoidentityprovider.ForgotPasswordInput{ ClientId: aws.String(clientId), Username: aws.String(userName), }) if err != nil { log.Printf("Couldn't start password reset for user '%v'. Here;s why: %v\n", userName, err) } return output.CodeDeliveryDetails, err } // ConfirmForgotPassword confirms a user with a confirmation code and a new password. func (actor CognitoActions) ConfirmForgotPassword(clientId string, code string, userName string, password string) error { _, err := actor.CognitoClient.ConfirmForgotPassword(context.TODO(), &cognitoidentityprovider.ConfirmForgotPasswordInput{ ClientId: aws.String(clientId), ConfirmationCode: aws.String(code), Password: aws.String(password), Username: aws.String(userName), }) if err != nil { var invalidPassword *types.InvalidPasswordException if errors.As(err, &invalidPassword) { log.Println(*invalidPassword.Message) } else { log.Printf("Couldn't confirm user %v. Here's why: %v", userName, err) } } return err } // DeleteUser removes a user from the user pool. func (actor CognitoActions) DeleteUser(userAccessToken string) error { _, err := actor.CognitoClient.DeleteUser(context.TODO(), &cognitoidentityprovider.DeleteUserInput{ AccessToken: aws.String(userAccessToken), }) if err != nil { log.Printf("Couldn't delete user. Here's why: %v\n", err) } return err } // AdminCreateUser uses administrator credentials to add a user to a user pool. This method leaves the user // in a state that requires they enter a new password next time they sign in. func (actor CognitoActions) AdminCreateUser(userPoolId string, userName string, userEmail string) error { _, err := actor.CognitoClient.AdminCreateUser(context.TODO(), &cognitoidentityprovider.AdminCreateUserInput{ UserPoolId: aws.String(userPoolId), Username: aws.String(userName), MessageAction: types.MessageActionTypeSuppress, UserAttributes: []types.AttributeType{{Name: aws.String("email"), Value: aws.String(userEmail)}}, }) if err != nil { var userExists *types.UsernameExistsException if errors.As(err, &userExists) { log.Printf("User %v already exists in the user pool.", userName) err = nil } else { log.Printf("Couldn't create user %v. Here's why: %v\n", userName, err) } } return err } // AdminSetUserPassword uses administrator credentials to set a password for a user without requiring a // temporary password. func (actor CognitoActions) AdminSetUserPassword(userPoolId string, userName string, password string) error { _, err := actor.CognitoClient.AdminSetUserPassword(context.TODO(), &cognitoidentityprovider.AdminSetUserPasswordInput{ Password: aws.String(password), UserPoolId: aws.String(userPoolId), Username: aws.String(userName), Permanent: true, }) if err != nil { var invalidPassword *types.InvalidPasswordException if errors.As(err, &invalidPassword) { log.Println(*invalidPassword.Message) } else { log.Printf("Couldn't set password for user %v. Here's why: %v\n", userName, err) } } return err }

创建一个封装 DynamoDB 操作的结构。

// DynamoActions encapsulates the Amazon Simple Notification Service (Amazon SNS) actions // used in the examples. type DynamoActions struct { DynamoClient *dynamodb.Client } // User defines structured user data. type User struct { UserName string UserEmail string LastLogin *LoginInfo `dynamodbav:",omitempty"` } // LoginInfo defines structured custom login data. type LoginInfo struct { UserPoolId string ClientId string Time string } // UserList defines a list of users. type UserList struct { Users []User } // UserNameList returns the usernames contained in a UserList as a list of strings. func (users *UserList) UserNameList() []string { names := make([]string, len(users.Users)) for i := 0; i < len(users.Users); i++ { names[i] = users.Users[i].UserName } return names } // PopulateTable adds a set of test users to the table. func (actor DynamoActions) PopulateTable(tableName string) error { var err error var item map[string]types.AttributeValue var writeReqs []types.WriteRequest for i := 1; i < 4; i++ { item, err = attributevalue.MarshalMap(User{UserName: fmt.Sprintf("test_user_%v", i), UserEmail: fmt.Sprintf("test_email_%v@example.com", i)}) if err != nil { log.Printf("Couldn't marshall user into DynamoDB format. Here's why: %v\n", err) return err } writeReqs = append(writeReqs, types.WriteRequest{PutRequest: &types.PutRequest{Item: item}}) } _, err = actor.DynamoClient.BatchWriteItem(context.TODO(), &dynamodb.BatchWriteItemInput{ RequestItems: map[string][]types.WriteRequest{tableName: writeReqs}, }) if err != nil { log.Printf("Couldn't populate table %v with users. Here's why: %v\n", tableName, err) } return err } // Scan scans the table for all items. func (actor DynamoActions) Scan(tableName string) (UserList, error) { var userList UserList output, err := actor.DynamoClient.Scan(context.TODO(), &dynamodb.ScanInput{ TableName: aws.String(tableName), }) if err != nil { log.Printf("Couldn't scan table %v for items. Here's why: %v\n", tableName, err) } else { err = attributevalue.UnmarshalListOfMaps(output.Items, &userList.Users) if err != nil { log.Printf("Couldn't unmarshal items into users. Here's why: %v\n", err) } } return userList, err } // AddUser adds a user item to a table. func (actor DynamoActions) AddUser(tableName string, user User) error { userItem, err := attributevalue.MarshalMap(user) if err != nil { log.Printf("Couldn't marshall user to item. Here's why: %v\n", err) } _, err = actor.DynamoClient.PutItem(context.TODO(), &dynamodb.PutItemInput{ Item: userItem, TableName: aws.String(tableName), }) if err != nil { log.Printf("Couldn't put item in table %v. Here's why: %v", tableName, err) } return err }

创建一个封装 CloudWatch Logs 操作的结构。

type CloudWatchLogsActions struct { CwlClient *cloudwatchlogs.Client } // GetLatestLogStream gets the most recent log stream for a Lambda function. func (actor CloudWatchLogsActions) GetLatestLogStream(functionName string) (types.LogStream, error) { var logStream types.LogStream logGroupName := fmt.Sprintf("/aws/lambda/%s", functionName) output, err := actor.CwlClient.DescribeLogStreams(context.TODO(), &cloudwatchlogs.DescribeLogStreamsInput{ Descending: aws.Bool(true), Limit: aws.Int32(1), LogGroupName: aws.String(logGroupName), OrderBy: types.OrderByLastEventTime, }) if err != nil { log.Printf("Couldn't get log streams for log group %v. Here's why: %v\n", logGroupName, err) } else { logStream = output.LogStreams[0] } return logStream, err } // GetLogEvents gets the most recent eventCount events from the specified log stream. func (actor CloudWatchLogsActions) GetLogEvents(functionName string, logStreamName string, eventCount int32) ( []types.OutputLogEvent, error) { var events []types.OutputLogEvent logGroupName := fmt.Sprintf("/aws/lambda/%s", functionName) output, err := actor.CwlClient.GetLogEvents(context.TODO(), &cloudwatchlogs.GetLogEventsInput{ LogStreamName: aws.String(logStreamName), Limit: aws.Int32(eventCount), LogGroupName: aws.String(logGroupName), }) if err != nil { log.Printf("Couldn't get log event for log stream %v. Here's why: %v\n", logStreamName, err) } else { events = output.Events } return events, err }

创建一个封装 Amazon CloudFormation 操作的结构。

// StackOutputs defines a map of outputs from a specific stack. type StackOutputs map[string]string type CloudFormationActions struct { CfnClient *cloudformation.Client } // GetOutputs gets the outputs from a CloudFormation stack and puts them into a structured format. func (actor CloudFormationActions) GetOutputs(stackName string) StackOutputs { output, err := actor.CfnClient.DescribeStacks(context.TODO(), &cloudformation.DescribeStacksInput{ StackName: aws.String(stackName), }) if err != nil || len(output.Stacks) == 0 { log.Panicf("Couldn't find a CloudFormation stack named %v. Here's why: %v\n", stackName, err) } stackOutputs := StackOutputs{} for _, out := range output.Stacks[0].Outputs { stackOutputs[*out.OutputKey] = *out.OutputValue } return stackOutputs }

清理资源。

// Resources keeps track of AWS resources created during an example and handles // cleanup when the example finishes. type Resources struct { userPoolId string userAccessTokens []string triggers []actions.Trigger cognitoActor *actions.CognitoActions questioner demotools.IQuestioner } func (resources *Resources) init(cognitoActor *actions.CognitoActions, questioner demotools.IQuestioner) { resources.userAccessTokens = []string{} resources.triggers = []actions.Trigger{} resources.cognitoActor = cognitoActor resources.questioner = questioner } // Cleanup deletes all AWS resources created during an example. func (resources *Resources) Cleanup() { defer func() { if r := recover(); r != nil { log.Printf("Something went wrong during cleanup.\n%v\n", r) log.Println("Use the AWS Management Console to remove any remaining resources \n" + "that were created for this scenario.") } }() wantDelete := resources.questioner.AskBool("Do you want to remove all of the AWS resources that were created "+ "during this demo (y/n)?", "y") if wantDelete { for _, accessToken := range resources.userAccessTokens { err := resources.cognitoActor.DeleteUser(accessToken) if err != nil { log.Println("Couldn't delete user during cleanup.") panic(err) } log.Println("Deleted user.") } triggerList := make([]actions.TriggerInfo, len(resources.triggers)) for i := 0; i < len(resources.triggers); i++ { triggerList[i] = actions.TriggerInfo{Trigger: resources.triggers[i], HandlerArn: nil} } err := resources.cognitoActor.UpdateTriggers(resources.userPoolId, triggerList...) if err != nil { log.Println("Couldn't update Cognito triggers during cleanup.") panic(err) } log.Println("Removed Cognito triggers from user pool.") } else { log.Println("Be sure to remove resources when you're done with them to avoid unexpected charges!") } }

有关 Amazon SDK 开发人员指南和代码示例的完整列表,请参阅 将 Lambda 与 Amazon SDK 配合使用。本主题还包括有关入门的信息以及有关先前的 SDK 版本的详细信息。