创建 Amazon Cognito 用户池后如何更改其属性?

3 分钟阅读
0

我创建了一个 Amazon Cognito 用户池,现在我想更改用户注册所需的标准属性。

简短描述

在创建用户池后,其标准属性是无法更改的。相反,要使用用户注册所需的属性创建一个新用户池。然后,使用 AWS Lambda 函数作为用户迁移触发器,将现有用户迁移到新的用户池

**注意:**您可以向现有用户池添加自定义属性,但这些属性不是用户注册所必需的属性。

解决方法

创建一个具有不同属性的新用户池

创建新用户池。然后,在选择创建池之前,根据自己的喜好编辑标准属性

重要事项:如果您在用户池中指定新的必需属性,则要设计您的 Lambda 函数将这些新属性传递给新用户池。如果不设计函数传递新属性,则在用户迁移期间身份验证将失败。例如,假设您的旧用户池只需要电子邮件,而您的新用户池需要电子邮件电话号码。在这种情况下,要将电话号码的属性值传递给您的新用户池,才能成功对用户进行身份验证。

创建 Lambda 函数

要创建用户迁移 Lambda 函数,请使用 Lambda 控制台编辑器构建并上传自己的部署包

**重要事项:**此示例代码不适用于迁移旧用户池中使用多重身份验证(MFA)的用户。

要测试您的配置,请在 Python 中使用以下示例函数:

# Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
# software and associated documentation files (the "Software"), to deal in the Software
# without restriction, including without limitation the rights to use, copy, modify,
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

import json
import boto3

client = boto3.client('cognito-idp')

def lambda_handler(event, context):
   if (event['triggerSource'] == 'UserMigration_Authentication'):
     user = client.admin_initiate_auth(
       UserPoolId='<user pool id of the user pool where the user already exists>',
       ClientId='<app client id of the user pool where the user already exists>',
       AuthFlow='ADMIN_NO_SRP_AUTH',
       AuthParameters={
         'USERNAME': event['userName'],
         'PASSWORD': event['request']['password']
       }
     )
        if (user):
       userAttributes = client.get_user(
         AccessToken=user['AuthenticationResult']['AccessToken']
       )
       for userAttribute in userAttributes['UserAttributes']:
         if userAttribute['Name'] == 'email':
           userEmail = userAttribute['Value']
           #print(userEmail)
           event['response']['userAttributes'] = {
             "email": userEmail,
             "email_verified": "true"
           }
          event['response']['messageAction'] = "SUPPRESS"
       print (event)
       return (event)
     else:
       return('Bad Password')
   elif (event["triggerSource"] == "UserMigration_ForgotPassword"):
     user = client.admin_get_user(
       UserPoolId='<user pool id of the user pool where the already user exists>',
       Username=event['userName']
     )
     if (user):
       for userAttribute in user['UserAttributes']:
         if userAttribute['Name'] == 'email':
           userEmail = userAttribute['Value']
           print(userEmail)
           event['response']['userAttributes'] = {
             "email": userEmail,
             "email_verified": "true"
           }
       event['response']['messageAction'] = "SUPPRESS"
          print (event)
       return (event)
     else:
       return('Bad Password')
          else:
     return('there was an error')

注意:请将 UserPoolId 替换为旧用户池的 ID。在 Amazon Cognito 控制台中找到该 ID,它位于用户池管理页面的常规设置选项卡中。将 ClientId 替换为旧用户池的应用程序客户端 ID。在 Amazon Cognito 控制台的应用程序客户端下找到应用程序客户端 ID。

向新用户池添加用户迁移触发器

Amazon Cognito 控制台中,将新 Lambda 函数设置为用户迁移 Lambda 触发器。有关更多信息,请参阅添加用户池 Lambda 触发器

为用户迁移启用 USER_PASSWORD_AUTH 流程

将用户池应用程序客户端配置为在迁移时使用 USER\ _PASSWORD\ _AUTH 身份验证流程。此身份验证流程会让应用程序将用户的用户名和密码传递给 Lambda 函数。然后,身份验证流程可以对现有用户池中的用户进行身份验证。

向应用程序添加逻辑,将默认身份验证流程更改为 USER\ _PASSWORD\ _AUTH 流程。如果用户在旧用户池中,但不在新用户池中,则让逻辑更改尝试登录时的身份验证流程。

例如,如果您的应用程序使用 JavaScript,请将 cognitoUser.setAuthenticationFlowType 指定为 USER\ _PASSWORD\ _AUTH

**注意:**迁移用户后,最佳做法是将应用程序的身份验证流程更改为 USER\ _SRP\ _AUTH。此流程使用安全远程密码 (SRP) 协议对用户进行身份验证,无需通过网络发送密码。与 USER\ _PASSWORD\ _AUTH 流程相比,此流程还具有安全优势。

cognitoUser.setAuthenticationFlowType('USER_PASSWORD_AUTH');
    cognitoUser.authenticateUser(authenticationDetails, {
        onSuccess: function(result) {
            // User authentication was successful
        },
        onFailure: function(err) {
            // User authentication was not successful
        },
        mfaRequired: function (codeDeliveryDetails) {
            // MFA is required to complete user authentication.
            // Get the code from user and call
            cognitoUser.sendMFACode(verificationCode, this);
        }
    });

测试设置

使用 Amazon Cognito 托管 Web UI 登录应用程序并测试身份验证流程。您登录时使用的用户将使用新用户池进行身份验证,然后进行迁移。

**注意:**如果您没有用户账户可供登录来测试您的配置,请创建一个新用户

疑难解答

如果您在测试时收到错误消息,例如“Exception during user migration”,请打开来自 Lambda 的日志语句。此设置将用户迁移 Lambda 触发器的参数记录到 Amazon CloudWatch Logs。重现错误,然后查看日志中是否存在任何参数问题或用户迁移 Lambda 触发器中的语法错误。

相关信息

使用 Lambda 触发器自定义用户池工作流

Amazon Cognito 用户池和身份池之间有什么区别?

用户池

AWS 官方
AWS 官方已更新 1 年前