我正在开发自定义无密码身份验证以登录Cognito用户池。我会描述一下,如果有什么事情是愚蠢的,我试图实施的是什么。我希望用户输入他们的电子邮件地址,然后通过电子邮件接收魔术登录链接,当他们点击它时,将被带回网站并登录。
这使用自定义身份验证lambda函数来定义/创建基于时间的密码的质询,并通过电子邮件将其发送给用户。我有几个问题:
问题1)
当用户返回代码时,他们可能不在同一个浏览器/设备中,并且肯定不会在同一个标签中,因此他们没有会话,这意味着我需要调用cognitoUser。再次发起启动。这会再次通过define / create challenge lambdas,因此即使此时用户来自电子邮件链接也已发送第二封电子邮件,因此已经有了代码。注意:创建挑战时,会话ID在事件对象中不可用,我也只在最近3分钟读取这些会话,而且我的基于时间的密码将持续约15分钟,所以我不认为我可以在电子邮件中包含会话ID。
问题2)
您可以从几个地方(浏览器,Android应用程序等)登录,我希望能够包含网址或至少协议作为参数来控制在电子邮件中发送的内容,例如如果您在Android应用程序中输入了您的电子邮件地址,那么您收到的电子邮件将是myapp:// login?code = xxx,如果您在网络上执行此操作,那将是https://example.com/login?code=xxx
似乎只要我能找到一些方法将自定义元数据发送到DefineChallenge和CreateChallenge lambda,以便它出现在事件对象中,我似乎能够实现这两者才能正常工作。我认为将ValidationData添加到AuthenticationDetails对象会执行此操作,但该信息不会出现在Lambda fns中的事件对象中。
我找到的解决方法是为每种情况创建一个新的客户端ID - 一个用于启动身份验证,一个用于兑换令牌,并为每个不同的协议重复。但这很快就会成为很多客户的责任 - 这是一种痛苦和笨拙的痛苦。
所以tl; dr是:我想从JS中的cognitoUser.initiateAuth(...)调用发送自定义元数据,并在我的Define / Create Challenge lambda fns中提供它。
答案 0 :(得分:0)
您可以将身份验证过程分为多个自定义身份验证挑战。这样就可以通过质询响应将自定义身份验证状态作为客户端元数据提供。
Auth会话状态必须保留在数据库中才能在设备之间共享。
您的自定义登录流程可能会有两个挑战步骤:第一个提示输入auth类型,第二个提示输入密码。 “创建身份验证挑战” Lambda采取的操作将取决于身份验证类型。如果身份验证类型为“电子邮件”,则将生成密码和魔术链接,并将其存储在DynamoDB中并通过电子邮件发送。如果身份验证类型为“ MagicLink”,则将从DynamoDB加载机密。单击魔术链接将启动一个新的身份验证会话,并自动提供所有挑战答案。
还有一些其他需要考虑的事情: