AWS Cognito 自定义身份验证 - 将元数据发送到质询 lambda 函数



我正在开发一个自定义的无密码身份验证来登录 Cognito 用户池。 我将描述我正在尝试实现的内容,以防万一有什么愚蠢的事情。 我希望用户输入他们的电子邮件地址,然后通过电子邮件收到一个神奇的登录链接,当他们点击该链接时,该链接将带回网站并登录。

这使用自定义身份验证 lambda 函数来定义/创建具有基于时间的密码的质询,并将其通过电子邮件发送给用户。 我遇到了几个问题:

问题 1)

当用户返回代码时,他们可能不在同一浏览器/设备中,当然也不会在同一个选项卡中,因此他们没有会话,这意味着我需要再次调用 cognitoUser.initiateAuth。这将再次通过定义/创建质询 lambda,因此即使此时用户来自电子邮件链接,因此已经拥有代码,也会发送第二封电子邮件。 注意:创建挑战时,会话 ID 在事件对象中不可用,而且我读取这些会话仅持续 3 分钟,我的基于时间的密码将持续 ~15 分钟,所以我认为我不能在电子邮件中包含会话 ID。

问题 2)

您可以从几个地方(浏览器、android 应用程序等)登录,我希望能够包含 url 或至少协议作为参数来控制电子邮件中发送的内容,例如,如果您在 android 应用程序中输入了您的电子邮件地址,那么您收到的电子邮件将是 myapp://登录?代码=xxx,如果你在网络上这样做,那将是 https://example.com/login?code=xxx

似乎只要我能找到某种方法将自定义元数据发送到 DefineChallenge 和 CreateChallenge lambda,使其出现在事件对象中,我就可以实现这两个正常工作。 我以为将 ValidationData 添加到 AuthenticationDetails 对象可以做到这一点,但该信息不会出现在 Lambda fns 的事件对象中。

我发现的解决方法是为每种情况创建一个新的客户端 ID - 一个用于启动身份验证,一个用于兑换令牌,并为每个不同的协议重复此操作。 但这很快就会有很多客户端 ID - 维护起来很痛苦而且很笨拙。

所以 tl;dr is:我想从我的 cognitoUser.initiateAuth(...) 调用中发送自定义元数据,并在我的定义/创建挑战 lambda fns 中提供它。

您可以将身份验证过程拆分为多个自定义身份验证质询。这允许通过质询响应将自定义身份验证状态作为客户端元数据提供。

身份验证会话状态必须保留在数据库中,才能在设备之间共享。

您的自定义登录流程可能有两个质询步骤:第一个提示身份验证类型,第二个提示输入密码。"创建身份验证质询"Lambda 执行的操作将取决于身份验证类型。如果身份验证类型为"电子邮件",则会生成密码和魔术链接,将其存储在 DynamoDB 中并通过电子邮件发送。如果身份验证类型为"MagicLink",则密钥将从 DynamoDB 加载。点击万智牌链接将启动一个新的身份验证会话,并自动提供所有挑战答案。

还有其他一些事项需要考虑:

  1. 您的魔术链接需要封装 Cognito 用户名以及一次性密钥,可能还有其他一些在 dynamodb 中用作密钥的会话 ID。
  2. 您可能不应该将特定于应用程序的链接放入电子邮件中。而是将您的域与您的应用相关联,和/或利用基于 Web 的登录页面的重定向 URI 参数。
  3. 您还可以从 Lambda 函数访问自定义 Cognito 用户属性,该属性可用于指示用户登录首选项(例如,电子邮件与短信的登录代码)。

基于@nathan所说的认知流程非常混乱,但可以通过多个步骤对元数据进行排序。流程基本上是

  1. 从 UI 发起登录请求。
  2. 首先被击中的是define auth challengeλ。这会查看过去的request.session项目,以确定已经完成或尚未完成的工作。第一次绕过时,会话列表是空的,所以你只需要要求一个挑战。这里重要的部分是你没有指定哪个挑战,只是需要挑战。定义步骤不知道自定义流/元数据
  3. 流中的下一个是create auth challenge您可以在其中设置流上的元数据,如果您需要从用户那里收集更多信息,这是您的机会。您可以将challengeMetadata字段设置为表示"要求用户提供更多数据"的字符串,并在publicChallengeParameters中将一些数据设置为"我需要更多"。
  4. 现在它命中您的 UI,您的 UI 可以查看初始身份验证请求的响应,并且应该在用户challengeParam字段中看到数据,这些数据应映射到您在创建身份验证中设置的公共参数。您的 UI 应提交质询响应,这是执行任务可能需要的所有额外元数据。
  5. 现在它去了verifyAuthChallenge. 在这里,您将查看会话,并看到会话元数据是您之前设置的"要求用户提供更多数据"字符串,您可以自动验证它(或进行自定义验证等)。此时,您可能希望将收集的数据存储在dynamo中,或者存储在尝试登录的用户名上的内容中。它已经过验证,您有用户名等。
  6. 现在它又回到了"定义身份验证质询"。在这里,您现在可以查看过去的会话,并看到"获取更多数据"步骤已完成,您可以要求更多数据(例如 2fa 代码)或继续说它们已完成。如果您再进行一轮并且此时需要原始元数据,则可以从dynamo加载它,然后执行任何您需要执行的操作

以这种愚蠢的方式,您现在可以收集和存储元数据,并将其保存在不同的自定义身份验证模式中。

我希望clientMetadata只是过得去,我们不必跳过这些箍,而是用你得到的东西工作。

最新更新