【发布时间】:2018-11-16 18:01:19
【问题描述】:
背景
我正在使用aws-amplify 与 Cognito 进行交互。所以当用户注册我的应用程序时,我会打电话给Auth.signUp()。我只将用户名(电子邮件)和密码传递给此函数。
我的用户池配置为仅允许通过电子邮件登录:
虫子?
在我的前端代码中,我不小心注册了两次事件侦听器,因此Auth.signUp() 被调用了两次(同时,或至少快速连续地)使用相同的参数。
这导致在我的用户池中创建了两个用户,使用相同的电子邮件。我对我的用户池配置的理解表明这是不可能的。
比赛条件?
我的第一个想法是,由于我发送的两个请求如此接近,这可能是某种不可避免的竞争条件。如果我在调用之间引入人为的暂停(比如断点或setTimeout),一切都会按预期进行。
但是,即使请求间隔非常紧密,第二个请求确实会返回我期望的错误响应:
{ code: 'InvalidParameterException',
name: 'InvalidParameterException',
message: 'Alias entry already exists for a different username'
}
遗憾的是,此响应具有误导性,因为我确实通过此请求在我的池中创建了第二个(重复的)用户。
MCVE
这很容易通过在节点脚本或浏览器中同时执行两次Auth.signUp 来重现。 This repository contains examples of both.
问题
- 这是 Cognito 的合法错误吗?
- preSignUp Lambda 触发器是我唯一防御这种情况的方法吗?如果是这样,该实施的大致流程是什么样的?
【问题讨论】:
-
我认为 Cognito 将允许两个用户使用相同的电子邮件注册,但只有一个用户能够验证/确认帐户。否则,有人可能会在系统上窃取您的电子邮件……但这可能不是您所看到的问题,具体取决于您的竞争条件。
-
@PaulHoenecke 感谢您的参与。似乎一秒钟是一个神奇的数字...如果我的通话间隔超过一秒钟,我不会得到两个在我的池中创建的用户。如果我的通话间隔不到一秒,我会这样做。如果第二个响应(创建重复用户)返回成功,我不会考虑这种错误行为。但是,很难将错误响应与正在创建的用户协调起来。如果创建了用户,我需要一个成功响应,以便我可以将有关用户的元数据填充到 DynamoDB 中。
-
相反,如果我收到来自
signUp()的错误响应,我想确信没有创建新用户。事实上,我得到的响应基本上是“抱歉,无法创建该用户”,但无论如何都会创建一个用户,只是感觉不对。我觉得被骗了。 -
这对我来说绝对是一个(或两个)错误。在这种情况下,如果只是检查 cognito 用户池中的现有电子邮件并且可能遭受相同的竞争条件,我认为常规的预注册触发器不会有帮助。您可以尝试插入具有唯一约束的 RDS 表,但这违背了在 cognito 中进行检查的目的,但是如果您的 cognito 注册由于其他原因而失败,则必须以某种方式将其删除。可能最好修复您的代码,向 AWS 提出问题,然后继续 :)
-
这是一个非常真实的错误,我也遇到过。
标签: javascript amazon-web-services amazon-cognito aws-amplify