本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
管理用户存在错误响应
Amazon Cognito 支持自定义由用户群体返回的错误响应。自定义错误响应可用于用户创建和身份验证、密码恢复和确认操作。
使用用户池应用程序客户端的 PreventUserExistenceErrors
设置,以启用或禁用用户存在相关错误。当您使用 Amazon Cognito 用户池 API 创建新的应用程序时,默认情况下 PreventUserExistenceErrors
为 LEGACY
或禁用。在 Amazon Cognito 控制台中,默认选定防止用户已存在错误选项(PreventUserExistenceErrors
设置为 ENABLED
)。要更新 PreventUserExistenceErrors
配置,请执行以下操作之一:
-
更改
PreventUserExistenceErrors
介LEGACY
于ENABLED
和之间的值 UpdateUserPoolClientAPI 请求。 -
在 Amazon Cognito 控制台中编辑应用程序客户端,并将防止用户已存在错误的状态更改为选定(
ENABLED
)和已取消选择(LEGACY
)。
当此属性的值为 LEGACY
时,当用户尝试使用您的用户池中不存在的用户名登录时,应用程序客户端会返回 UserNotFoundException
错误响应。
当此属性的值为 ENABLED
时,应用程序客户端不会通过 UserNotFoundException
错误来透露您的用户池中不存在某个用户账户。PreventUserExistenceErrors
配置为 ENABLED
具有以下影响:
-
Amazon Cognito 会使用非特定信息响应 API 请求,否则其响应可能会泄露存在有效的用户。
-
Amazon Cognito 登录和忘记密码会 APIs 返回一般的身份验证失败响应。错误响应告知您用户名或密码不正确。
-
Amazon Cognito 账户确认和密码恢复会 APIs 返回一个响应,表示代码已发送到模拟传送媒体,而不是部分显示用户的联系信息。
以下信息详细说明了 PreventUserExistenceErrors
设置为 ENABLED
时用户池操作的行为。
身份验证和用户创建操作
您可以在用户名/密码和安全远程密码(SRP)身份验证中配置错误响应。您还可以对使用自定义身份验证返回的错误进行自定义。以下人员 APIs 执行这些身份验证操作:
-
AdminInitiateAuth
-
AdminRespondToAuthChallenge
-
InitiateAuth
-
RespondToAuthChallenge
以下列表演示了如何在用户身份验证操作中自定义错误响应。
- 用户名和密码身份验证
-
要使用
ADMIN_USER_PASSWORD_AUTH
和USER_PASSWORD_AUTH
登录用户,请在AdminInitiateAuth
或InitiateAuth
API 请求中包含用户名和密码。在用户名或密码不正确时,Amazon Cognito 返回一个通用NotAuthorizedException
错误。 - 基于安全远程密码(SRP)的身份验证
-
最佳做法是,仅在没有电子邮件地址、电话号码或首选用户名别名属性的用户池中
PreventUserExistenceErrors
使用 SRP 身份验证来实现。在 SRP 身份验证流程中,具有别名属性的用户可能不会受到禁止用户存在的限制。用户名密码身份验证完全禁止用户通过别名属性存在。要使用
USER_SRP_AUTH
登录用户,请在AdminInitiateAuth
或InitiateAuth
API 请求中包含用户名和SRP_A
参数。作为响应,Amazon Cognito 为用户返回SRP_B
和盐值。如果找不到用户,Amazon Cognito 会在第一步中返回一个模拟响应,如 RFC 5054中所述。Amazon Cognito 始终针对相同的用户名和用户池组合返回相同的盐值以及 UUID 格式的内部用户 ID。当您发送带有密码证明的 RespondToAuthChallenge
API 时,Amazon Cognito 在用户名或密码不正确时返回一个通用NotAuthorizedException
错误。注意
如果您使用基于验证的别名属性,并且不可改变的用户名格式不是 UUID,则可以模拟使用用户名和密码身份验证的通用响应。
- 自定义身份验证质询 Lambda 触发器
-
如果您使用自定义身份验证质询 Lambda 触发器并启用错误响应,则
LambdaChallenge
将返回一个名为UserNotFound
的布尔值参数。然后它在DefineAuthChallenge
、VerifyAuthChallenge
和CreateAuthChallenge
Lambda 触发器请求后传递。您可以使用此触发器来模拟不存在用户的自定义授权质询。如果您为不存在的用户调用预身份验证 Lambda 触发器,则 Amazon Cognito 将返回UserNotFound
。
以下列表演示了如何在用户创建操作中自定义错误响应。
- SignUp
-
当已使用用户名时,
SignUp
操作始终返回UsernameExistsException
。如果在您的应用程序中注册用户时,您不希望 Amazon Cognito 为电子邮件地址和电话号码返回UsernameExistsException
错误,请使用基于验证的别名属性。有关别名的更多信息,请参阅自定义登录属性。有关 Amazon Cognito 如何阻止使用
SignUp
API 请求来发现用户群体中用户的示例,请参阅 在注册时防止出现电子邮件地址和电话号码的 UsernameExistsException 错误。 - 导入的用户
-
如果
PreventUserExistenceErrors
已启用,则在对导入的用户进行身份验证期间,将返回通用NotAuthorizedException
错误,指示用户名或密码不正确,而不是返回PasswordResetRequiredException
。请参阅要求导入的用户重置密码,了解更多信息。 - 迁移用户 Lambda 触发器
-
当 Lambda 触发器在原始事件上下文中设置了空响应时,Amazon Cognito 将为不存在的用户返回模拟响应。有关更多信息,请参阅迁移用户 Lambda 触发器。
在注册时防止出现电子邮件地址和电话号码的 UsernameExistsException
错误
以下示例演示了在用户群体中配置别名属性时,如何在对 SignUp
API 请求的响应中,防止重复的电子邮件地址和电话号码生成 UsernameExistsException
错误。您必须在创建用户群体时使用电子邮件地址或电话号码作为别名属性。有关更多信息,请参阅用户群体属性的自定义登录属性 部分。
-
Jie 注册了一个新的用户名,还提供了电子邮件地址
jie@example.com
。Amazon Cognito 将向其电子邮件地址发送一个代码。Amazon CLI 命令示例
aws cognito-idp sign-up --client-id 1234567890abcdef0 --username jie --password PASSWORD --user-attributes Name="email",Value="jie@example.com"
响应示例
{ "UserConfirmed": false, "UserSub": "
<subId>
", "CodeDeliveryDetails": { "AttributeName": "email", "Destination": "j****@e****", "DeliveryMedium": "EMAIL" } } -
Jie 提供了发送过来的代码,确认其拥有该电子邮件地址。这样就完成了用户注册。
Amazon CLI 命令示例
aws cognito-idp confirm-sign-up --client-id 1234567890abcdef0 --username=jie --confirmation-code xxxxxx
-
Shirley 注册了一个新的用户账户并提供了电子邮件地址
jie@example.com
。Amazon Cognito 不会返回UsernameExistsException
错误,而是向 Jie 的电子邮件地址发送确认代码。Amazon CLI 命令示例
aws cognito-idp sign-up --client-id 1234567890abcdef0 --username shirley --password PASSWORD --user-attributes Name="email",Value="jie@example.com"
响应示例
{ "UserConfirmed": false, "UserSub": "
<new subId>
", "CodeDeliveryDetails": { "AttributeName": "email", "Destination": "j****@e****", "DeliveryMedium": "EMAIL" } } -
在另一种情况下,Shirley 拥有对
jie@example.com
的所有权。Shirley 收到了 Amazon Cognito 发送到 Jie 电子邮件地址的代码,并尝试确认该账户。Amazon CLI 命令示例
aws cognito-idp confirm-sign-up --client-id 1234567890abcdef0 --username=shirley --confirmation-code xxxxxx
响应示例
An error occurred (AliasExistsException) when calling the ConfirmSignUp operation: An account with the email already exists.
尽管已将 jie@example.com
分配给现有用户,Amazon Cognito 不会对 Shirley 的 aws cognito-idp sign-up
请求返回错误。在 Amazon Cognito 返回错误响应之前,Shirley 必须证明对该电子邮件地址的所有权。在具有别名属性的用户群体中,此行为会阻止使用公共 SignUp
API 来检查是否存在具有给定电子邮件地址或电话号码的用户。
此行为与 Amazon Cognito 向使用现有用户名的 SignUp
请求返回的响应不同,如以下示例所示。尽管 Shirley 从此回复中得知已经存在具有用户名 jie
的用户,但他们并不知道与该用户关联的任何电子邮件地址或电话号码。
示例 CLI 命令
aws cognito-idp sign-up --client-id 1example23456789 --username jie --password PASSWORD --user-attributes Name="email",Value="shirley@example.com"
响应示例
An error occurred (UsernameExistsException) when calling the SignUp operation: User already exists
密码重置操作
当您防止出现用户存在错误时,Amazon Cognito 会对用户密码重置操作返回以下响应。
- ForgotPassword
-
当找不到用户、用户已停用或没有经过验证的传送机制来恢复其密码时,Amazon Cognito 会为用户返回
CodeDeliveryDetails
以及模拟的传递媒介。模拟的传递媒介由用户池的输入用户名格式和验证设置决定。 - ConfirmForgotPassword
-
Amazon Cognito 为不存在或已禁用的用户返回
CodeMismatchException
错误。如果在使用ForgotPassword
时不请求代码,Amazon Cognito 将返回ExpiredCodeException
错误。
确认操作
当您防止出现用户存在错误时,Amazon Cognito 会对用户确认和验证操作返回以下响应。
- ResendConfirmationCode
-
Amazon Cognito 为已禁用或不存在的用户返回
CodeDeliveryDetails
。Amazon Cognito 会向现有用户的电子邮件或电话发送确认码。 - ConfirmSignUp
-
如果代码已过期,则将返回
ExpiredCodeException
。当用户未被授权时,Amazon Cognito 返回NotAuthorizedException
。如果代码与服务器期望的代码不匹配,则 Amazon Cognito 返回CodeMismatchException
。