

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 注册并确认用户账户
<a name="signing-up-users-in-your-app"></a>

可通过以下任一方法将用户账户添加到您的用户池中：
+ 用户在您用户池的客户端应用程序中进行注册。这可以是移动应用程序或 Web 应用程序。
+ 您可以将用户账户导入到用户池中。有关更多信息，请参阅 [通过 CSV 文件将用户导入用户池中](cognito-user-pools-using-import-tool.md)。
+ 您可以在用户池中创建用户账户并邀请用户登录。有关更多信息，请参阅 [以管理员身份创建用户账户](how-to-create-user-accounts.md)。

自行注册的用户必须得到确认才可登录。导入和创建的用户已经过确认，但他们必须在首次登录时创建自己的密码。以下部分将介绍确认过程以及电子邮件和电话验证。

**注册时的密码**  
Amazon Cognito 要求所有用户在注册时提供密码，但以下情况除外。如果满足*所有*这些条件，则可以在注册操作中忽略密码。

1. [无密码登录](amazon-cognito-user-pools-authentication-flow-methods.md#amazon-cognito-user-pools-authentication-flow-methods-passwordless)在您的用户池和应用程序客户端中处于活动状态。

1. 您的应用程序是使用 Amazon SDK 中的身份验证模块定制的。托管登录和托管 UI 始终要求提供密码。

1. 用户为您允许的无密码登录方法（电子邮件或短信一次性密码 ()OTPs）提供属性值。例如，如果您允许使用电子邮件和电话 OTP 登录，则用户可以提供电话号码或电子邮件地址，但是如果您只允许使用电子邮件登录，则他们必须提供电子邮件地址。

1. 您的用户池会[自动验证](#allowing-users-to-sign-up-and-confirm-themselves)用户可在无密码登录中使用的属性。

1. 对于任何给定的[SignUp](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_SignUp.html)请求，用户都不会为 P [asswor](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_SignUp.html#CognitoUserPools-SignUp-request-Password) d 参数提供值。

## 用户账户确认概览
<a name="signup-confirmation-verification-overview"></a>

下图阐明了确认过程：

![\[当用户输入确认代码时，将自动验证电子邮件或电话。\]](http://docs.amazonaws.cn/cognito/latest/developerguide/images/amazon-cognito-sign-in-confirm-user.png)


用户账户可以处于以下任一状态：

**已注册（未确认）**  
用户已成功注册，但在用户账户得到确认之前无法登录。在此状态下，用户已启用，但未得到确认。  
自行注册的新用户由此状态开始。

**已确认**  
用户账户已确认，用户可以登录。当用户输入代码或点击电子邮件链接以确认其用户账户时，系统将自动验证电子邮件或电话号码。代码或链接的有效期为 24 小时。  
如果管理员或预注册 Lambda 触发器确认了用户账户，则可能没有与该账户关联的经验证的电子邮件或电话号码。

**需要重置密码**  
用户账户已确认，但用户必须请求代码并重置其密码，然后才可以登录。  
由管理员或开发人员导入的用户账户以此状态开始。

**强制更改密码**  
用户账户已确认，用户可以使用临时密码进行登录。但在首次登录时，用户必须将其密码更改为新值，然后才能执行任何其他操作。  
由管理员或开发人员创建的用户账户以此状态开始。

**已禁用**  
在可以删除用户账户之前，必须禁用该用户的登录访问权限。

**更多资源**
+ [使用 Amazon Cognito 检测和修复不活跃的用户账户](https://www.amazonaws.cn/blogs/security/detecting-and-remediating-inactive-user-accounts-with-amazon-cognito/)

## 在注册时验证联系人信息
<a name="allowing-users-to-sign-up-and-confirm-themselves"></a>

当新用户注册您的应用程序时，您可能希望他们提供至少一种联系方式。例如，利用用户的联系人信息，您可以：
+ 在用户选择重置其密码时发送临时密码。
+ 在更新用户的个人信息或财务信息后向用户发送通知。
+ 发送促销信息（例如，特别优惠或折扣）。
+ 发送账户摘要或账单提醒。

对于像这样的使用案例，将消息发送到经过验证的目的地非常重要。否则，您可能会将消息发送到错误键入的无效电子邮件地址或电话号码。或者更糟糕的是，您可能会将敏感信息发送给冒充您的用户的坏人。

为了帮助确保您仅将消息发送给正确的人员，请配置您的 Amazon Cognito 用户池以使用户在注册时必须提供以下内容：

1. 一个电子邮件地址或电话号码。

1. Amazon Cognito 发送到该电子邮件地址或电话号码的验证码。如果 24 小时过去并且您的用户的代码或链接不再有效，请调用 [ResendConfirmationCode](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_ResendConfirmationCode.html)API 操作生成并发送新的代码或链接。

通过提供验证码，用户可以证明他们有权访问收到该代码的邮箱或手机。在用户提供该代码后，Amazon Cognito 将通过以下方式更新用户池中的用户相关信息：
+ 将用户的状态设置为 `CONFIRMED`。
+ 更新用户的属性以指示已验证电子邮件地址或电话号码。

要查看此信息，您可以使用 Amazon Cognito 控制台。或者，您可以使用 `AdminGetUser` API 操作、带的`admin-get-user` Amazon CLI命令或其中一个中的相应操作 Amazon SDKs。

如果用户具有经验证的联系方式，Amazon Cognito 会在用户请求重置密码时自动向其发送消息。

### 确认和验证用户属性的其他操作
<a name="allowing-users-to-sign-up-and-confirm-themselves-other-actions"></a>

以下用户活动会验证用户属性。您无需将这些属性设置为自动验证：列出的操作在所有情况下都会将其标记为已验证。

**电子邮件地址**  

1. 使用电子邮件一次性密码（OTP）成功完成[无密码身份验证](amazon-cognito-user-pools-authentication-flow-methods.md#amazon-cognito-user-pools-authentication-flow-methods-passwordless)。

1. 使用电子邮件 OTP 成功完成[多重身份验证（MFA）](user-pool-settings-mfa.md)。

**Phone number（电话号码）**  

1. 使用短信 OTP 成功完成[无密码身份验证](amazon-cognito-user-pools-authentication-flow-methods.md#amazon-cognito-user-pools-authentication-flow-methods-passwordless)。

1. 使用短信 OTP 成功完成 [MFA](user-pool-settings-mfa.md)。

### 配置您的用户池以要求电子邮件或手机验证
<a name="verification-configure"></a>

验证用户的电子邮件地址和电话号码时，确保可以联系到用户。完成中的以下步骤， Amazon Web Services 管理控制台 将您的用户池配置为要求您的用户确认其电子邮件地址或电话号码。

**注意**  
如果您的账户中还没有用户池，请参阅[用户池入门](getting-started-user-pools.md)。

**配置用户池**

1. 导航到 [Amazon Cognito 控制台](https://console.amazonaws.cn/cognito/home)。如果出现提示，请输入您的 Amazon 凭据。

1. 从导航窗格中选择**用户池**。从列表中选择一个现有用户池，或[创建一个用户池](https://docs.amazonaws.cn/cognito/latest/developerguide/cognito-user-pool-as-user-directory.html)。

1. 选择**登录**菜单，然后找到**属性验证和用户账户确认**。选择**编辑**。

1. 在 **Cognito 辅助验证和确认**下，选择是否**允许 Cognito 自动发送消息以进行验证和确认**。启用此设置后，当用户注册或您创建用户配置文件时，Amazon Cognito 会向您选择的用户联系人属性发送消息。为验证属性并确认登录的用户配置文件，Amazon Cognito 会通过消息向用户发送代码或链接。用户随后必须在您的 UI 中输入相应代码，这样，您的应用才能在 `ConfirmSignUp` 或 `AdminConfirmSignUp` API 请求中对其进行确认。
**注意**  
您还可以禁用 **Cognito 辅助验证和确认**并使用经过身份验证的 API 操作或 Lambda 触发器验证属性并确认用户。  
如果您选择此选项，则 Amazon Cognito 不会在用户注册时发送验证码。如果您要使用自定义身份验证流程验证至少一种联系方式，而不使用来自 Amazon Cognito 的验证码，请选择此选项。例如，您可以使用一个预注册 Lambda 触发器，该触发器将自动验证属于特定域的电子邮件地址。  
如果您不验证用户的联系人信息，用户可能无法使用您的应用程序。请记住，用户需要经验证的联系人信息才能：  
**重置密码** – 当用户在您的应用程序中选择调用 `ForgotPassword` API 操作的选项时，Amazon Cognito 会将临时密码发送到用户的电子邮件地址或电话号码。Amazon Cognito 仅在用户具有至少一个经验证的联系方式时发送此密码。
**通过使用电子邮箱地址或电话号码作为别名进行登录** – 如果您将用户池配置为允许这些别名，则用户只能在别名经过验证后使用别名进行登录。有关更多信息，请参阅 [自定义登录属性](user-pool-settings-attributes.md#user-pool-settings-aliases)。

1. 选择您的**要验证的属性**：  
**发送 SMS 消息，验证电话号码**  
Amazon Cognito 将在用户注册时通过 SMS 消息发送验证码。如果您通常通过 SMS 消息与用户通信，请选择此选项。例如，如果您要发送交付通知、约会确认或提醒，则将需要使用经过验证的电话号码。确认账户时，用户电话号码将成为已验证属性；您必须采取其它操作来验证用户电子邮件地址并与其进行通信。  
**发送电子邮件消息，验证电子邮件地址**  
Amazon Cognito 将在用户注册时通过电子邮件发送验证码。如果您通常通过电子邮件与用户通信，请选择此选项。例如，如果您要发送账单、订单摘要或特别优惠，则将需要使用经过验证的电子邮件地址。确认账户时，用户电子邮件地址将成为已验证属性；您必须采取其它操作来验证用户电话号码并与其进行通信。  
**如果电话号码可用，则发送 SMS 消息，否则发送电子邮件**  
如果您不要求所有用户都拥有相同的经验证的联系方式，请选择此选项。在这种情况下，您的应用程序中的注册页面可能会要求用户仅验证其首选联系方式。当 Amazon Cognito 发送验证码时，会将该代码发送到来自您应用程序的 `SignUp` 请求中提供的联系方式。如果用户同时提供了电子邮件地址和电话号码，并且您的应用程序在 `SignUp` 请求中提供了这两种联系方式，Amazon Cognito 将仅向电话号码发送验证码。  
如果您要求用户同时验证电子邮件地址和电话号码，则选择此选项。Amazon Cognito 将在用户注册时验证一种联系方式，而且您的应用程序必须在用户登录后验证另一种联系方式。有关更多信息，请参阅 [在您要求用户确认电子邮件地址和电话号码的情况下](#verification-email-plus-phone)。

1. 选择**保存更改**。

### 使用电子邮件或电话验证的身份验证流程
<a name="verification-flow"></a>

如果您的用户池要求用户验证其联系人信息，则当用户注册时，您的应用程序必须促进以下流程：

1. 用户通过输入用户名、电话号码、 and/or 电子邮件地址以及可能的其他属性来注册您的应用程序。

1. Amazon Cognito 服务接收来自应用程序的注册请求。验证该请求包含注册所需的所有属性后，该服务将完成注册过程并向用户的手机（通过 SMS 消息）或电子邮件发送确认码。代码的有效期为 24 小时。

1. 该服务向应用程序返回信息，表示注册过程已完成且用户账户正等待确认。响应中包含关于确认代码所发送到位置的信息。此时，用户账户处于未确认状态，而且用户的电子邮件地址和电话号码未经验证。

1. 现在，应用程序会提示用户输入确认代码。用户无需立即输入代码。但是，用户只有在输入确认代码后才可登录。

1. 用户在应用程序中输入确认代码。

1. 应用程序调用 [https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_ConfirmSignUp.html](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_ConfirmSignUp.html) 将代码发送到 Amazon Cognito 服务，该服务将验证代码并在代码正确时将用户账户设置为已确认状态。成功确认用户账户之后，Amazon Cognito 服务会自动将用于确认（电子邮件地址或电话号码）的属性标记为已验证。除非此属性的值发生更改，否则用户无需再次进行验证。

1. 此时，用户账户处于已确认状态，用户可以登录。

### 在您要求用户确认电子邮件地址和电话号码的情况下
<a name="verification-email-plus-phone"></a>

Amazon Cognito 在用户注册时仅验证一种联系方式。如果 Amazon Cognito 必须在验证电子邮件地址或电话号码之间进行选择，则会选择通过 SMS 消息发送验证码来验证电话号码。例如，如果您将用户池配置为允许用户验证电子邮件地址或电话号码，并且您的应用程序在注册时提供了这两个属性，则 Amazon Cognito 将仅验证电话号码。在用户验证其电话号码后，Amazon Cognito 会将用户的状态设置为 `CONFIRMED`，并允许用户登录您的应用程序。

在用户登录后，您的应用程序会提供相应选项来验证在注册期间未验证的联系方式。为了验证第二种联系方式，您的应用程序将调用 `VerifyUserAttribute` API 操作。请注意，此操作需要 `AccessToken` 参数，而 Amazon Cognito 只为经过身份验证的用户提供访问令牌。因此，您只能在用户登录后验证第二种联系方式。

如果您要求用户同时验证电子邮件地址和电话号码，请执行以下操作：

1. 配置用户池以允许用户验证电子邮件地址或电话号码。

1. 在应用程序的注册流程中，要求用户提供电子邮件地址和电话号码。调用 [https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_SignUp.html](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_SignUp.html) API 操作，并为 `UserAttributes` 参数提供电子邮件地址和电话号码。此时，Amazon Cognito 会向用户的手机发送一个验证码。

1. 在应用程序界面中，会显示一个确认页面以供用户输入验证码。通过调用 [https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_ConfirmSignUp.html](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_ConfirmSignUp.html) API 操作来确认用户。此时，用户的状态为 `CONFIRMED`，并且用户的电话号码已验证，但电子邮件地址未验证。

1. 显示登录页，并通过调用 [https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html) API 操作对用户进行身份验证。对用户进行身份验证后，Amazon Cognito 将向您的应用程序返回访问令牌。

1. 调用 [https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_GetUserAttributeVerificationCode.html](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_GetUserAttributeVerificationCode.html) API 操作。在请求中指定以下参数：
   + `AccessToken` – Amazon Cognito 在用户登录时返回的访问令牌。
   + `AttributeName` – 将 `"email"` 指定为属性值。

   Amazon Cognito 将向用户的电子邮件地址发送一个验证码。

1. 显示一个确认页面以供用户输入验证码。当用户提交代码时，请调用 [https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_VerifyUserAttribute.html](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_VerifyUserAttribute.html) API 操作。在请求中指定以下参数：
   + `AccessToken` – Amazon Cognito 在用户登录时返回的访问令牌。
   + `AttributeName` – 将 `"email"` 指定为属性值。
   + `Code` – 用户提供的验证码。

   此时，电子邮件地址已验证。

## 允许用户在您的应用程序中注册但以用户池管理员身份进行确认
<a name="signing-up-users-in-your-app-and-confirming-them-as-admin"></a>

您可能不希望您的用户池自动在用户池中发送验证消息，但仍希望允许任何人注册账户。例如，该模型为人工审查新的注册请求以及批量验证和处理注册留出了空间。您可以在 Amazon Cognito 控制台中或通过 IAM 身份验证的 API 操作确认新的用户账户。[AdminConfirmSignUp](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_AdminConfirmSignUp.html)无论您的用户池是否发送验证消息，您都能以管理员身份确认用户账户。

您只能使用此方法确认用户的自助注册。要确认您以管理员身份创建的用户，请创建`Permanent`设置为[AdminSetUserPassword](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_AdminSetUserPassword.html)的 API 请求`True`。

1. 用户通过输入用户名、电话号码、 and/or 电子邮件地址以及可能的其他属性来注册您的应用程序。

1. Amazon Cognito 服务接收来自应用程序的注册请求。验证该请求包含注册所需的所有属性之后，该服务将完成注册过程，并向应用程序返回信息，表示注册已完成且正在等待确认。此时，用户账户处于未确认状态。账户经过确认后，用户才可登录。

1. 确认用户的账户。您必须使用 Amazon 凭据登录 Amazon Web Services 管理控制台 或签署 API 请求才能确认账户。

   1. 要在 Amazon Cognito 控制台中确认用户，请导航到**用户**菜单，选择要确认的用户，然后从**操作**菜单中选择**确认**。

   1. 要在 Amazon API 或 CLI 中确认用户，请创建 [AdminConfirmSignUp](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_AdminConfirmSignUp.html)API 请求，或者[admin-confirm-sign-up](https://docs.amazonaws.cn/cli/latest/reference/cognito-idp/admin-confirm-sign-up.html)在 Amazon CLI。

1. 此时，用户账户处于已确认状态，用户可以登录。

## 计算密钥哈希值
<a name="cognito-user-pools-computing-secret-hash"></a>

作为最佳实践，请将客户端密钥分配给您的机密应用程序客户端。当您向应用程序客户端分配客户端密钥时，您的 Amazon Cognito 用户池 API 请求必须包括一个哈希值，用于包含请求正文中的客户端密钥。为了验证您对以下列表中 API 操作的客户端密钥的了解，请将客户端密钥与应用程序客户端 ID 和用户的用户名连接起来，然后对该字符串进行 base64 编码。

应用程序将用户登录到具有密钥哈希值的客户端时，您可以使用任何用户池登录属性的值作为密钥哈希值的用户名元素。应用程序在使用 `REFRESH_TOKEN_AUTH` 的身份验证操作中请求新令牌时，用户名元素的值取决于您的登录属性。如果您的用户池没有将 `username` 用作登录属性，请通过用户的访问令牌或 ID 令牌中的 `sub` 声明设置密钥哈希用户名值。如果 `username` 为登录属性，请通过 `username` 声明设置密钥哈希用户名值。

以下 Amazon Cognito 用户池 APIs 接受参数中的客户端密钥哈希值。`SecretHash`
+ [https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_ConfirmForgotPassword.html](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_ConfirmForgotPassword.html)
+ [https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_ConfirmSignUp.html](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_ConfirmSignUp.html)
+ [https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_ForgotPassword.html](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_ForgotPassword.html)
+ [https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_ResendConfirmationCode.html](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_ResendConfirmationCode.html)
+ [https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_SignUp.html](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_SignUp.html)

此外，以下内容 APIs 接受`SECRET_HASH`参数中的客户端密钥哈希值，无论是在身份验证参数中还是在质询响应中。


| API 操作 | SECRET\$1HASH 的父参数 | 
| --- |--- |
| InitiateAuth | AuthParameters | 
| AdminInitiateAuth | AuthParameters | 
| RespondToAuthChallenge | ChallengeResponses | 
| AdminRespondToAuthChallenge | ChallengeResponses | 

密钥哈希值是 Base 64 编码的加密哈希消息身份验证代码（HMAC，Hash Message Authentication Code），使用用户池客户端的私有密钥、用户名以及消息中的客户端 ID 进行计算。以下伪代码显示如何计算此值。在此伪代码中，`+`表示串联，表示使用 Hmac 生成 HMAC 值的函数，并`HMAC_SHA256``Base64`表示生成 Base-64 编码SHA256版本的哈希输出的函数。

```
Base64 ( HMAC_SHA256 ( "Client Secret Key", "Username" + "Client Id" ) )
```

有关如何计算和使用`SecretHash`参数的详细概述，请参阅[如何解决我的 Amazon Cognito 用户池 API 中的 “无法验证客户端的秘密哈希” 错误？](https://www.amazonaws.cn/premiumsupport/knowledge-center/cognito-unable-to-verify-secret-hash/)<client-id> 在 Amazon 知识中心中。

您可以在服务器端应用程序代码中使用以下代码示例：

------
#### [ Shell ]

```
echo -n "[username][app client ID]" | openssl dgst -sha256 -hmac [app client secret] -binary | openssl enc -base64
```

------
#### [ Java ]

```
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
 
public static String calculateSecretHash(String userPoolClientId, String userPoolClientSecret, String userName) {
    final String HMAC_SHA256_ALGORITHM = "HmacSHA256";
    
    SecretKeySpec signingKey = new SecretKeySpec(
            userPoolClientSecret.getBytes(StandardCharsets.UTF_8),
            HMAC_SHA256_ALGORITHM);
    try {
        Mac mac = Mac.getInstance(HMAC_SHA256_ALGORITHM);
        mac.init(signingKey);
        mac.update(userName.getBytes(StandardCharsets.UTF_8));
        byte[] rawHmac = mac.doFinal(userPoolClientId.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(rawHmac);
    } catch (Exception e) {
        throw new RuntimeException("Error while calculating ");
    }
}
```

------
#### [ Python ]

```
import sys
import hmac, hashlib, base64 
username = sys.argv[1] 
app_client_id = sys.argv[2] 
key = sys.argv[3] 
message = bytes(sys.argv[1]+sys.argv[2],'utf-8') 
key = bytes(sys.argv[3],'utf-8') 
secret_hash = base64.b64encode(hmac.new(key, message, digestmod=hashlib.sha256).digest()).decode() 
print("SECRET HASH:",secret_hash)
```

------

## 无需验证电子邮件或电话号码即可确认用户账户
<a name="confirming-user-without-verification-of-email-or-phone-number"></a>

预注册 Lambda 触发器可用于在注册时自动确认用户账户，而无需提供确认码或者验证电子邮件或电话号码。通过此方法进行确认的用户可立即登录，而无需接收代码。

您还可通过此触发器将用户的电子邮件或电话号码标记为已验证。

**注意**  
虽然这种方法对刚入门的用户而言很方便，但建议至少自动验证电子邮件或电话号码之一。否则，如果用户忘记密码，可能就无法进行恢复。

如果您不要求用户在注册时接收并输入确认码，也不在预注册 Lambda 触发器中自动验证电子邮件和电话号码，则您将承担对于该用户账户不具备经验证的电子邮件地址或电话号码的风险。用户可以稍后验证电子邮件地址或电话号码。但是，如果用户忘记自己的密码且没有经验证的电子邮件地址或电话号码，则用户将被锁定而无法使用账户，因为忘记密码流程需要经验证的电子邮件或电话号码以便向用户发送验证码。

## 当用户更改其电子邮件或电话号码时应进行验证
<a name="verifying-when-users-change-their-email-or-phone-number"></a>

在您配置了多个登录名的用户池中，用户可以在登录时输入电话号码或电子邮件地址作为用户名。当用户在应用程序中更新其电子邮件地址或电话号码时，Amazon Cognito 会立即向他们发送带有验证码的消息，用于验证其对新属性值的所有权。要启用自动发送这些验证码，请参阅[配置电子邮件或电话验证](user-pool-settings-email-phone-verification.md)。

收到验证码的用户必须在请求中将该验证码提供给 Amazon Cognito。[VerifyUserAttribute](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_VerifyUserAttribute.html)提供验证码后，他们的属性将被标记为已验证。通常，当用户更新其电子邮件地址或电话号码时，您需要先验证他们是否拥有这个新值，然后他们才能使用新值登录和接收消息。用户池有一个可配置的选项，用于确定用户是否必须验证其电子邮件地址或电话号码的更新信息。

此选项是用户池属性 `AttributesRequireVerificationBeforeUpdate`。在[CreateUserPool](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html#CognitoUserPools-CreateUserPool-request-UserAttributeUpdateSettings)或[UpdateUserPool](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPool.html#CognitoUserPools-UpdateUserPool-request-UserAttributeUpdateSettings)请求中对其进行配置，或者在 Amazon Cognito 控制台**的 “**注册**” 菜单中使用待更新时保持原始属性值处于活动状态**设置。

您的用户池如何处理电子邮件地址和电话号码的更新与用户池的用户名配置有关。用户池用户名可以位于*用户名属性*配置中，其中登录名为电子邮件地址、电话号码或两者兼而有之。它们也可以位于*别名属性*配置中，其中 `username` 属性是登录名，电子邮件地址、电话号码或首选用户名作为备用登录名。有关更多信息，请参阅[自定义登录属性](user-pool-settings-attributes.md#user-pool-settings-aliases)。

 您也可以使用自定义消息 Lambda 触发器来自定义验证消息。有关更多信息，请参阅 [自定义消息 Lambda 触发器](user-pool-lambda-custom-message.md)。当用户的电子邮件地址或电话号码未经验证时，您的应用程序应通知用户必须验证该属性，并为用户提供一个按钮或链接来输入其验证码。

下表描述了当用户更改其登录属性的值时，`AttributesRequireVerificationBeforeUpdate` 和别名设置如何确定结果。


| 用户名配置 | 用户必须验证新属性时的行为 | 用户不需要验证新属性时的行为 | 
| --- | --- | --- | 
| 用户名属性 | 原始属性仍处于已验证状态，有资格登录，且为原始值。当用户验证新值时，Amazon Cognito 会更新属性值，将其标记为已验证，并使其符合登录资格。 | Amazon Cognito 将属性更新为新值。新值具有登录资格。当用户验证新值时，Amazon Cognito 会将其标记为已验证。 | 
| 别名属性 | 原始属性仍处于已验证状态，有资格登录，且为原始值。当用户验证新值时，Amazon Cognito 会更新属性值，将其标记为已验证，并使其符合登录资格。 | Amazon Cognito 将属性更新为新值。原始属性值或新属性值均无登录资格。当用户验证新值时，Amazon Cognito 会更新属性值，将其标记为已验证，并使其符合登录资格。 | 

**示例 1**  
用户 1 使用电子邮件地址 `user1@example.com` 登录您的应用程序，用户名为 `user1`（别名属性）。您的用户池配置为验证登录属性的更新并自动发送验证消息。他们请求将其电子邮件地址更新为 `user1+foo@example.com`。他们通过 `user1+foo@example.com` 接收验证电子邮件，并且只能使用电子邮件地址 `user1@example.com` *重新登录*。之后，他们输入验证码，并且只能使用电子邮件地址 `user1+foo@example.com` 重新登录。

**示例 2**  
用户 2 使用电子邮件地址 `user2@example.com` 登录您的应用程序，并提供用户名（别名属性）。您的用户池配置为*不*验证登录属性的更新并自动发送验证消息。他们请求将其电子邮件地址更新为 `user2+bar@example.com`。他们通过 `user2+bar@example.com` 接收验证电子邮件，并且*无法重新登录*。之后，他们输入验证码，并且只能使用电子邮件地址 `user2+bar@example.com` 重新登录。

**示例 3**  
用户 3 使用电子邮件地址 `user3@example.com` 登录您的应用程序，没有提供用户名（用户名属性）。您的用户池配置为*不*验证登录属性的更新并自动发送验证消息。他们请求将其电子邮件地址更新为 `user3+baz@example.com`。他们通过 `user3+baz@example.com` 接收验证电子邮件，但是他们*可以立即登录*，无需使用验证码执行任何其他操作。

## 针对由管理员或开发人员创建的用户账户的确认和验证过程
<a name="confirmation-and-verification-of-users-whose-accounts-youve-created"></a>

由管理员或开发人员创建的用户账户已经处于已确认状态，所以用户无需输入确认代码。Amazon Cognito 服务向这些用户发送的邀请消息包含用户名和临时密码。用户需要在登录前更改密码。有关更多信息，请参阅[自定义电子邮件和 SMS 消息](how-to-create-user-accounts.md#creating-a-new-user-customize-messages)中的 [以管理员身份创建用户账户](how-to-create-user-accounts.md)和[使用 Lambda 触发器自定义用户池工作流](cognito-user-pools-working-with-lambda-triggers.md)中的自定义消息触发器。

## 针对导入的用户账户的确认和验证过程
<a name="confirmation-and-verification-of-users-whose-accounts-youve-imported"></a>

使用 Amazon Web Services 管理控制台、CLI 或 API 中的用户导入功能（参见[通过 CSV 文件将用户导入用户池中](cognito-user-pools-using-import-tool.md)）创建的用户账户已处于已确认状态，因此用户无需输入确认码。没有发送邀请消息。但是，导入的用户账户要求用户首先调用 `ForgotPassword` API 来请求代码，然后通过调用 `ConfirmForgotPassword` API 来使用发送的代码创建密码，之后方可登录。有关更多信息，请参阅 [要求导入的用户重置密码](cognito-user-pools-using-import-tool.md#cognito-user-pools-using-import-tool-password-reset)。

导入用户账户时，用户的电子邮件或电话号码必须已标记为已验证，从而用户无需验证即可登录。

## 在测试应用程序时发送电子邮件
<a name="managing-users-accounts-email-testing"></a>

当用户在您的用户池的客户端应用程序中创建和管理其账户时，Amazon Cognito 将向用户发送电子邮件。如果您将用户池配置为要求电子邮件验证，Amazon Cognito 将在以下情况下发送电子邮件：
+ 用户注册。
+ 用户更新其电子邮件地址。
+ 用户执行一项调用 `ForgotPassword` API 操作的操作。
+ 您以管理员身份创建用户账户。

根据发起电子邮件递送的操作，电子邮件将包含验证码或临时密码。您的用户必须接收这些电子邮件并理解消息。否则，他们可能无法登录并使用您的应用程序。

要确保电子邮件成功发送并且邮件看起来正确，请测试应用程序中从 Amazon Cognito 启动电子邮件传送的操作。例如，通过使用应用程序中的注册页面或通过使用 `SignUp` API 操作，您可以通过使用测试电子邮件地址进行注册来启动电子邮件传送。在通过此方式进行测试时，请记住以下几点：

**重要提示**  
当您使用电子邮件地址测试从 Amazon Cognito 启动电子邮件传送的操作时，请勿使用虚假的电子邮件地址（没有邮箱的电子邮件地址）。使用真实的电子邮件地址才能接收来自 Amazon Cognito 的电子邮件，而不会创建*查无此人的邮件*。  
在 Amazon Cognito 未能将电子邮件传送到收件人邮箱时会产生查无此人的邮件，如果邮箱不存在，则始终会发生这种情况。  
Amazon Cognito 限制了持续出现硬退邮件的 Amazon 账户可以发送的电子邮件数量。

当您测试启动电子邮件传送的操作时，请使用下列电子邮件地址之一以防止出现查无此人的邮件：
+ 您拥有的用于测试的电子邮件账户的地址。当您使用自己的电子邮件地址时，您将收到 Amazon Cognito 发送的电子邮件。利用此电子邮件，您可以使用验证码来测试应用程序中的注册体验。如果您为用户池自定义了电子邮件，则可检查自定义项看起来是否正确。
+ 邮箱模拟器地址：*success@simulator.amazonses.com*。如果您使用模拟器地址，Amazon Cognito 将成功发送电子邮件，但您无法查看。当您不需要使用验证码并且不需要检查电子邮件时，此选项很有用。
+ 添加了任意标签的邮箱模拟器地址（如 *success\$1user1@simulator.amazonses.com* 或 *success\$1user2@simulator.amazonses.com*）。Amazon Cognito 可成功向这些地址发送电子邮件，但您无法查看其发送的电子邮件。当您希望通过向用户池添加多个测试用户来测试注册过程，并且每个测试用户都具有一个唯一的电子邮件地址时，此选项很有用。