Amazon Cognito
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 Amazon AWS 入门

注册并确认用户账户

可通过以下任一方法将用户账户添加到您的用户池中:

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

用户账户确认概述

下图阐明了确认过程:


        当用户输入确认代码时,将自动验证电子邮件或电话。

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

已注册 (未确认)

用户已成功注册,但在用户账户得到确认之前无法登录。在此状态下,用户已启用,但未得到确认。

自行注册的新用户由此状态开始。

已确认

用户账户已确认,用户可以登录。如果用户输入通过电子邮件或手机 (SMS) 收到的确认代码(如果是通过电子邮件,则单击确认链接),从而确认了用户账户,则系统将自动验证该电子邮件或电话号码。代码或链接的有效期为 24 小时。

如果管理员或预注册 Lambda 触发器确认了用户账户,则可能没有与账户关联的经验证电子邮件或电话号码。

需要重置密码

用户账户已确认,但用户必须请求代码并重置其密码才可登录。

由管理员或开发人员导入的用户账户以此状态开始。

强制更改密码

用户账户已确认,用户可以使用临时密码进行登录,但在首次登录时,用户必须将其密码更改为新值,然后才能执行其他操作。

由管理员或开发人员创建的用户账户以此状态开始。

已停用

必须先禁用用户账户才可将其删除。

在注册时验证联系人信息

当新用户注册您的应用程序时,您可能希望他们提供至少一种联系方式。例如,利用用户的联系人信息,您可以:

  • 在用户选择重置其密码时发送临时密码。

  • 在更新用户的个人信息或财务信息后向用户发送通知。

  • 发送促销信息(例如,特别优惠或折扣)。

  • 发送账户摘要或账单提醒。

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

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

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

  2. Amazon Cognito 发送到该电子邮件地址或电话号码的一个验证码。

通过提供验证码,用户可以证明其有权访问收到该代码的邮箱或手机。在用户提供该代码后,Amazon Cognito 将通过以下方式更新用户池中的用户相关信息:

  • 将用户的状态设置为 CONFIRMED

  • 更新用户的属性以指示已验证电子邮件地址或电话号码。

要查看此信息,您可以使用 Amazon Cognito 控制台。或者,您可以使用 AdminGetUser API 操作、带 AWS CLI 的 admin-get-user 命令或某个 AWS 开发工具包中的相应操作。

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

配置您的用户池以要求电子邮件或手机验证

通过要求电子邮件或手机验证,有助于确保您可通过可靠方式来联系您的用户。完成以下步骤以使用 Amazon Cognito 控制台配置用户池。

开始之前

如果您还没有用户池,则需要在您的账户中配置用户池。如需创建一个角色,请参阅 用户池入门

配置用户池

  1. 通过 https://console.amazonaws.cn/cognito 登录 AWS 管理控制台并打开 Amazon Cognito 控制台。

  2. 选择管理用户池

  3. Your User Pools (您的用户池) 页面上,选择要配置的用户池。

  4. 在左侧导航菜单中,选择 MFA and verifications (MFA 和验证)

    电子邮件或手机验证的选项显示在 Which attributes do you want to verify? (您要验证哪些属性?)

    
            要求用户验证电子邮件地址或电话号码以注册您的应用程序的用户池配置选项。
  5. 请选择以下任一选项:

    电子邮件

    如果您选择此选项,Amazon Cognito 将在用户注册时通过电子邮件发送验证码。如果您通常通过电子邮件与用户通信,请选择此选项。例如,如果您要发送账单、订单摘要或特别优惠,则将需要使用经过验证的电子邮件地址。

    电话号码

    如果您选择此选项,Amazon Cognito 将在用户注册时通过 SMS 发送验证码。如果您通常通过 SMS 与用户通信,请选择此选项。例如,如果您要发送交付通知、约会确认或提醒,则将需要使用经过验证的电话号码。

    电子邮件或电话号码

    如果您不要求所有用户都拥有相同的经验证的联系方式,请选择此选项。在这种情况下,您的应用程序中的注册页面可能会要求用户仅验证其首选联系方式。当 Amazon Cognito 发送验证码时,它会将该代码发送到来自您的应用程序的 SignUp 请求中提供的联系方式。如果用户同时提供了电子邮件地址和电话号码,并且您的应用程序在 SignUp 请求中提供了这两种联系方式,Amazon Cognito 将仅向电话号码发送验证码。

    如果您要求用户同时验证电子邮件地址和电话号码,请选择此选项。Amazon Cognito 将在用户注册时验证一种联系方式,您的应用程序必须在用户登录后验证另一种联系方式。有关更多信息,请参阅在您要求用户确认电子邮件地址和电话号码的情况下

    如果您选择此选项,则 Amazon Cognito 不会在用户注册时发送验证码。如果您要使用一个自定义身份验证流程,该流程将验证至少一种联系方式而不使用来自 Amazon Cognito 的验证码,请选择此选项。例如,您可以使用一个预注册 Lambda 触发器,该触发器将自动验证属于特定域的电子邮件地址。

    如果您不验证用户的联系人信息,用户在某些情况下可能无法使用您的应用程序。请记住,用户需要经验证的联系人信息才能:

    • 重置其密码。当用户在您的应用程序中执行调用 ForgotPassword API 操作的操作时,Amazon Cognito 会将临时密码发送到用户的电子邮件地址或电话号码。Amazon Cognito 仅在用户具有至少一个经验证的联系方式时发送此密码。

    • 通过将电子邮件地址或电话号码用作别名来进行登录。如果您将用户池配置为允许这些别名,则用户只能在别名经过验证后使用别名进行登录。有关更多信息,请参阅别名概述

  6. 选择 Save changes

使用电子邮件或电话验证的身份验证流程

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

  1. 用户通过输入用户名称、电话号码和/或电子邮件地址及其他可能属性,在您的应用程序中进行注册。

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

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

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

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

  6. 应用程序调用 ConfirmSignUp 以将代码发送到 Amazon Cognito 服务,该服务将验证代码并在代码正确时将用户账户设置为已确认状态。成功确认用户账户之后,Amazon Cognito 服务会自动将用于确认 (电子邮件或电话号码) 的属性标记为已验证。除非此属性的值发生更改,否则用户无需再次进行验证。

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

在您要求用户确认电子邮件地址和电话号码的情况下

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

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

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

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

  2. 在应用程序的注册流程中,要求用户提供电子邮件地址和电话号码。调用 SignUp API 操作,并为 UserAttributes 参数提供电子邮件地址和电话号码。此时,Amazon Cognito 会向用户的手机发送一个验证码。

  3. 在应用程序界面中,会显示一个确认页面以供用户输入验证码。通过调用 ConfirmSignUp API 操作来确认用户。此时,用户的状态为 CONFIRMED,并且用户的电话号码已验证,但电子邮件地址未验证。

  4. 显示登录页,并通过调用 InitiateAuth API 操作对用户进行身份验证。对用户进行身份验证后,Amazon Cognito 将向您的应用程序返回访问令牌。

  5. 调用 GetUserAttributeVerificationCode API 操作。在请求中指定以下参数:

    • AccessToken – Amazon Cognito 在用户登录时返回的访问令牌。

    • AttributeName – 将 "email" 指定为属性值。

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

  6. 显示一个确认页面以供用户输入验证码。当用户提交代码时,请调用 VerifyUserAttribute API 操作。在请求中指定以下参数:

    • AccessToken – Amazon Cognito 在用户登录时返回的访问令牌。

    • AttributeName – 将 "email" 指定为属性值。

    • Code – 用户提供的验证码。

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

允许用户在您的应用程序中注册但以管理员身份进行确认

  1. 用户通过输入用户名称、电话号码和/或电子邮件地址及其他可能属性,在您的应用程序中进行注册。

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

  3. 管理员在 Amazon Cognito 控制台(通过在用户选项卡中查找用户账户并选择确认按钮)或 CLI(通过使用 admin-confirm-sign-up 命令)中确认用户账户。Confirm (确认) 按钮和 admin-confirm-sign-up 命令都使用 AdminConfirmSignUp API 来执行确认。

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

计算 SecretHash 值

以下 Amazon Cognito 用户池 API 具有 SecretHash 参数:

SecretHash 值是的 Base 64 编码的加密哈希消息身份验证代码 (HMAC),使用用户池客户端的私有密钥、用户名称以及消息中的客户端 ID 进行计算。以下伪代码显示此值是如何计算得出的。在此伪代码中,+ 表示串联,HMAC_SHA256 代表使用 HmacSHA256 生成 HMAC 值的函数,Base64 代表生成哈希输出的 Base-64 编码版本的函数。

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

或者,您可以在服务器端 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 "); } }

无需验证电子邮件或电话号码即可确认用户账户

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

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

注意

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

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

当用户更改其电子邮件或电话号码时应进行验证

当用户在您的应用程序中更改其电子邮件地址或电话号码时,该属性将标记为未经验证。如果针对所更新的属性启用了自动验证,则该服务将立即向用户发送包含验证代码的消息,用户应输入此代码以验证更改。您可以使用自定义消息 Lambda 触发器来自定义此消息。有关更多信息,请参阅 使用 Lambda 触发器自定义用户池工作流。每当用户的电子邮件地址或电话号码未经过验证时,您的应用程序均应显示未经验证状态,并为用户提供一个按钮或链接,以验证其新的电子邮件或电话号码。

针对由管理员或开发人员创建的用户账户的确认和验证过程

由管理员或开发人员创建的用户账户已经处于已确认状态,所以用户无需输入确认代码。Amazon Cognito 服务向这些用户发送的邀请消息包含用户名称和临时密码。用户需要在登录前更改密码。有关更多信息,请参阅Message Customizations 选项卡中的 以管理员身份创建用户账户使用 Lambda 触发器自定义用户池工作流中的自定义消息触发器。

针对导入的用户账户的确认和验证过程

使用 AWS 管理控制台、CLI 或 API 中的用户导入功能创建的用户账户(请参阅通过 CSV 文件将用户导入用户池中)已处于已确认状态,因此用户无需输入确认代码。没有发送邀请消息。但是,导入的用户账户要求用户首先调用 ForgotPassword API 来请求代码,然后通过调用 ConfirmForgotPassword API 来使用发送的代码创建密码,之后方可登录。有关更多信息,请参阅要求导入的用户重置密码

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

在测试应用程序时发送电子邮件

当用户在用户池的客户端应用程序中创建和管理其账户时,Amazon Cognito 将向用户发送电子邮件。如果您将用户池配置为要求电子邮件验证,Amazon Cognito 将在以下情况下发送电子邮件:

  • 用户注册。

  • 用户更新其电子邮件地址。

  • 用户执行一项调用 ForgotPassword API 操作的操作。

  • 您以管理员身份创建用户账户。

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

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

重要提示

当您使用电子邮件地址来测试从 Amazon Cognito 启动电子邮件传送的操作时,请勿使用虚假的电子邮件地址(没有邮箱的电子邮件地址)。使用真实的电子邮件地址以便接收来自 Amazon Cognito 的电子邮件而不创建查无此人的邮件

查无此人的邮件在 Amazon Cognito 未能将电子邮件传送到收件人邮箱时产生,此情况在邮箱不存在时始终出现。

Amazon Cognito 将限制持续产生查无此人的邮件的 AWS 账户可发送的电子邮件的数量。

当您测试启动电子邮件传送的操作时,请使用下列电子邮件地址之一以防止出现查无此人的邮件:

  • 您拥有的用于测试的电子邮件账户的地址。当您使用自己的电子邮件地址时,您将收到 Amazon Cognito 发送的电子邮件。利用此电子邮件,您可以使用验证码来测试应用程序中的注册体验。如果您为用户池自定义了电子邮件,则可检查自定义项看起来是否正确。

  • 邮箱模拟器地址:success@simulator.amazonses.com。如果您使用模拟器地址,Amazon Cognito 将成功发送电子邮件,但您无法查看它。当您不需要使用验证码并且不需要检查电子邮件时,此选项很有用。

  • 添加了任意标签的邮箱模拟器地址(如 success+user1@simulator.amazonses.comsuccess+user2@simulator.amazonses.com)。Amazon Cognito 可通过电子邮件成功发送这些地址,但您无法查看其发送的电子邮件。当您希望通过向用户池添加多个测试用户来测试注册过程,并且每个测试用户都具有一个唯一的电子邮件地址时,此选项很有用。