多个社交提供商的 AWS Cognito 联合身份:合并身份或将它们分开更好?
AWS Cognito Federated Identities for multiple social providers: better to merge identities or keep them separate?
多个 AWS Cognito 联合身份(例如 Facebook 和同一电子邮件的 Google 登录)可以通过在 Cognito 调用中传递两个登录合并为一个身份。但是知道我可以合并身份并不能回答我是否应该合并身份。
合并身份与保持身份分离的优缺点是什么? (我们将用户配置文件存储在我们自己的数据库中;我们不使用 Cognito 用户池。如果我们不合并身份,那么我们的后端数据库会将每个身份 ID 的映射存储到我们后台的正确用户 ID -结束数据库。)
这是当同一用户尝试使用 Facebook 和 Google 进行身份验证时应用程序的当前工作流程:
- 在客户端(这是一个网络应用程序)上,新用户点击登录并选择使用 Facebook 登录。
- 客户端代码将用户登录到 Cognito Federated Identities 并获取新的联合身份 ID,该 ID 被授权调用我们的 AWS Lambda 函数。
- 客户端调用我们的
getOrCreateUserProfile
Lambda 函数,该函数使用 Cognito Identity ID 作为密钥来查看该 Cognito 身份是否已与用户相关联。
- 因为在我们的数据库中没有找到具有此身份 ID 的其他用户,并且因为没有其他用户有此电子邮件地址(因为它是一个全新的用户),那么我们的 Lambda 函数将在我们的数据库中创建一个新的用户配置文件数据库和 return 配置文件返回给用户。
- 稍后,用户尝试使用 Google.
登录(在同一设备或另一设备上)
- 为此 Google 身份创建了一个新的联合身份。
- 我们的
getOrCreateUserProfile
Lambda 函数找不到与此身份 ID 匹配的现有用户,但确实找到了具有相同电子邮件地址的另一个用户。
此时我们有三种选择:
- A) Return 给用户的一个错误,例如“请使用您的 Facebook 帐户登录”。这是我们想要改变的当前行为。
- B) 通过要求用户也使用 Facebook 登录来合并身份,然后将两个身份传递给 Cognito,Cognito 将合并它们。参见
- C) 在我们的后端数据库中添加一个映射行以将新身份映射到用户的现有用户配置文件。现在这个用户将有两个联合身份:一个使用 Facebook 提供者,一个使用 Google 提供者。
选项 (B) 与选项 (C) 的优缺点是什么?以下是此比较的起点。 pros/cons 我错过了什么?
合并身份
- 专业版
- Simpler/faster 次查找,因为每个用户只有一个身份 ID 必须在后端编制索引
- 我认为这是最安全的解决方案?
- 缺点
- 合并过程本身看起来很复杂且容易出错。例如,合并后,如果新 ID“赢得”合并,那么我们需要用用户配置文件中的新 ID 替换旧 ID……如果在此过程中出现问题,我们可能会留在一种不可恢复的状态,其中 Cognito 只知道新的(合并的)ID,而我们的数据库只知道旧的。
- 更复杂的用户体验,用户必须在同一会话中同时登录(尽管只登录一次)Facebook 和 Google 帐户才能 link 这些帐户。
- 以后对 linking 的任何更改都必须通过 Cognito API
保持分离
- 专业版
- 更简单的用户体验:我们可以通过匹配电子邮件地址来 link 社交帐户;无需在一个会话中同时登录
- 可以单独控制 linking 在我们的后端数据库中,这应该可以更容易地构建管理工具 add/remove/change identity->user-profile links 而不是不得不调用 Cognito 的 API 来执行这些操作。
- 没有 Cognito 与我们的后端数据库不同步的风险。如果 linking 失败,用户可以简单地重试。
- 缺点
- 需要 many:1 索引来映射身份 ID -> 用户配置文件,而不是单个索引列
- 这是一个不太安全的解决方案吗?如果是,为什么?
- 这在 AWS 费用中是否更昂贵?如果是,为什么?
我倾向于“保持独立”解决方案,因为它似乎更易于实施(没有额外的 UX 工作流程)并且对用户来说更容易(出于同样的原因:没有新的 UX 工作流程)。这是一个错误吗?
很难给你答案,我想你已经提供了所有可能解决方案的主要优缺点。
我只会尝试澄清其中的一些,我认为这是选择一种解决方案而不是另一种解决方案的关键。
首先,表明我也更喜欢保持独立的解决方案。让我试着解释一下原因。
从用户体验的角度来看,保持独立的解决方案显然对用户来说是一种更好的方法。要合并不同社交提供者的身份,用户需要在更复杂的应用程序注册工作流程中使用它们登录。但这个过程只是出于技术决策的动机,不会为用户提供任何实际利益。
我认为一个更好更简单的解决方案是按照您在保持独立解决方案中建议的那样在每个身份和关联的电子邮件之间包含一个映射,并让用户通过他或她更喜欢在您的应用程序代码中透明地“合并”所有这些登录机制。无论您用于存储用户信息的底层信息系统的类型如何,都可以轻松实现此要求。
请考虑一下,如果您需要在您的应用程序中包含另一个不同的社交提供商,并且现有用户想要通过该新提供商登录您的应用程序,将会发生什么情况:如何合并身份?用户是否应该再次重复该过程?
此外,身份合并功能是 Cognito 特有的功能。如果您采用合并解决方案,您将承担将您的应用程序与 AWS 和 AWS Cognito 紧密耦合的风险。如果您需要将您的应用程序移动到另一个云提供商或 on-premises 部署,您可能无法进行此类关联。同样,在保持独立解决方案中采用的某种身份信息与内部用户模型之间的映射似乎是一种更好且可移植的方法。
与 Cognito 不同步的风险可能是另一个大问题。恢复机制是什么?
保持独立解决方案的唯一真正缺点可能是您可能会向 AWS 支付更多费用。正如您在 product pricing documentation 中所见,AWS 将按每月活跃用户 (MAU) 向您收费。如果你有更多的身份,就像保持独立的解决方案一样,可能会有更多的 MAU,你可能会产生更高的成本。在任何情况下,这些成本都不会高很多,不过,我相信 keep separate 解决方案提供的优势将弥补这一最低价格上涨。
最后,我不认为保持独立的解决方案是一个不太安全的选择:虽然看起来您正在联合身份以允许您的用户与 AWS 服务交互,但无论用户提供的实际身份。
我认为合并解决方案最适合您拥有联合并且需要唯一标识用户的场景,无论他们如何进行身份验证,但可能会强制执行与仅基于这些特定身份使用 AWS 资源,并且可能在您没有可用的应用程序后端时使用。
无论最终采用哪种解决方案,一个关键的成功因素是保持用户模型和相关逻辑尽可能独立于用于验证用户的机制:保持独立的解决方案也有助于以这种方式思考.
从用户的角度来看,通过第二个提供者登录却发现他们有 none 以前的内容可能会让人感到非常困惑和不安。从这个角度来看,我认为合并将是最好的最终目标。
现在从技术角度来看,我对此有所了解,发现这很麻烦。当用户首先使用电子邮件登录然后使用社交媒体登录时,我设法合并了身份,但反之则不然。我想唯一的选择是有一个 pre-signup lambda 触发器来检查数据库中该特定电子邮件的先前登录,并要求用户也登录这些电子邮件以进行合并或只是继续登录现有的。如果不止一个 pre-existing 登录,这说起来容易做起来难。
关于谁“赢得”合并的问题,总是pre-existing。最后也没有关系,因为所有登录都将通过调用使用相同的 Cognito 联合 ID。
多个 AWS Cognito 联合身份(例如 Facebook 和同一电子邮件的 Google 登录)可以通过在 Cognito 调用中传递两个登录合并为一个身份。但是知道我可以合并身份并不能回答我是否应该合并身份。
合并身份与保持身份分离的优缺点是什么? (我们将用户配置文件存储在我们自己的数据库中;我们不使用 Cognito 用户池。如果我们不合并身份,那么我们的后端数据库会将每个身份 ID 的映射存储到我们后台的正确用户 ID -结束数据库。)
这是当同一用户尝试使用 Facebook 和 Google 进行身份验证时应用程序的当前工作流程:
- 在客户端(这是一个网络应用程序)上,新用户点击登录并选择使用 Facebook 登录。
- 客户端代码将用户登录到 Cognito Federated Identities 并获取新的联合身份 ID,该 ID 被授权调用我们的 AWS Lambda 函数。
- 客户端调用我们的
getOrCreateUserProfile
Lambda 函数,该函数使用 Cognito Identity ID 作为密钥来查看该 Cognito 身份是否已与用户相关联。 - 因为在我们的数据库中没有找到具有此身份 ID 的其他用户,并且因为没有其他用户有此电子邮件地址(因为它是一个全新的用户),那么我们的 Lambda 函数将在我们的数据库中创建一个新的用户配置文件数据库和 return 配置文件返回给用户。
- 稍后,用户尝试使用 Google. 登录(在同一设备或另一设备上)
- 为此 Google 身份创建了一个新的联合身份。
- 我们的
getOrCreateUserProfile
Lambda 函数找不到与此身份 ID 匹配的现有用户,但确实找到了具有相同电子邮件地址的另一个用户。
此时我们有三种选择:
- A) Return 给用户的一个错误,例如“请使用您的 Facebook 帐户登录”。这是我们想要改变的当前行为。
- B) 通过要求用户也使用 Facebook 登录来合并身份,然后将两个身份传递给 Cognito,Cognito 将合并它们。参见
- C) 在我们的后端数据库中添加一个映射行以将新身份映射到用户的现有用户配置文件。现在这个用户将有两个联合身份:一个使用 Facebook 提供者,一个使用 Google 提供者。
选项 (B) 与选项 (C) 的优缺点是什么?以下是此比较的起点。 pros/cons 我错过了什么?
合并身份
- 专业版
- Simpler/faster 次查找,因为每个用户只有一个身份 ID 必须在后端编制索引
- 我认为这是最安全的解决方案?
- 缺点
- 合并过程本身看起来很复杂且容易出错。例如,合并后,如果新 ID“赢得”合并,那么我们需要用用户配置文件中的新 ID 替换旧 ID……如果在此过程中出现问题,我们可能会留在一种不可恢复的状态,其中 Cognito 只知道新的(合并的)ID,而我们的数据库只知道旧的。
- 更复杂的用户体验,用户必须在同一会话中同时登录(尽管只登录一次)Facebook 和 Google 帐户才能 link 这些帐户。
- 以后对 linking 的任何更改都必须通过 Cognito API
保持分离
- 专业版
- 更简单的用户体验:我们可以通过匹配电子邮件地址来 link 社交帐户;无需在一个会话中同时登录
- 可以单独控制 linking 在我们的后端数据库中,这应该可以更容易地构建管理工具 add/remove/change identity->user-profile links 而不是不得不调用 Cognito 的 API 来执行这些操作。
- 没有 Cognito 与我们的后端数据库不同步的风险。如果 linking 失败,用户可以简单地重试。
- 缺点
- 需要 many:1 索引来映射身份 ID -> 用户配置文件,而不是单个索引列
- 这是一个不太安全的解决方案吗?如果是,为什么?
- 这在 AWS 费用中是否更昂贵?如果是,为什么?
我倾向于“保持独立”解决方案,因为它似乎更易于实施(没有额外的 UX 工作流程)并且对用户来说更容易(出于同样的原因:没有新的 UX 工作流程)。这是一个错误吗?
很难给你答案,我想你已经提供了所有可能解决方案的主要优缺点。
我只会尝试澄清其中的一些,我认为这是选择一种解决方案而不是另一种解决方案的关键。
首先,表明我也更喜欢保持独立的解决方案。让我试着解释一下原因。
从用户体验的角度来看,保持独立的解决方案显然对用户来说是一种更好的方法。要合并不同社交提供者的身份,用户需要在更复杂的应用程序注册工作流程中使用它们登录。但这个过程只是出于技术决策的动机,不会为用户提供任何实际利益。
我认为一个更好更简单的解决方案是按照您在保持独立解决方案中建议的那样在每个身份和关联的电子邮件之间包含一个映射,并让用户通过他或她更喜欢在您的应用程序代码中透明地“合并”所有这些登录机制。无论您用于存储用户信息的底层信息系统的类型如何,都可以轻松实现此要求。
请考虑一下,如果您需要在您的应用程序中包含另一个不同的社交提供商,并且现有用户想要通过该新提供商登录您的应用程序,将会发生什么情况:如何合并身份?用户是否应该再次重复该过程?
此外,身份合并功能是 Cognito 特有的功能。如果您采用合并解决方案,您将承担将您的应用程序与 AWS 和 AWS Cognito 紧密耦合的风险。如果您需要将您的应用程序移动到另一个云提供商或 on-premises 部署,您可能无法进行此类关联。同样,在保持独立解决方案中采用的某种身份信息与内部用户模型之间的映射似乎是一种更好且可移植的方法。
与 Cognito 不同步的风险可能是另一个大问题。恢复机制是什么?
保持独立解决方案的唯一真正缺点可能是您可能会向 AWS 支付更多费用。正如您在 product pricing documentation 中所见,AWS 将按每月活跃用户 (MAU) 向您收费。如果你有更多的身份,就像保持独立的解决方案一样,可能会有更多的 MAU,你可能会产生更高的成本。在任何情况下,这些成本都不会高很多,不过,我相信 keep separate 解决方案提供的优势将弥补这一最低价格上涨。
最后,我不认为保持独立的解决方案是一个不太安全的选择:虽然看起来您正在联合身份以允许您的用户与 AWS 服务交互,但无论用户提供的实际身份。
我认为合并解决方案最适合您拥有联合并且需要唯一标识用户的场景,无论他们如何进行身份验证,但可能会强制执行与仅基于这些特定身份使用 AWS 资源,并且可能在您没有可用的应用程序后端时使用。
无论最终采用哪种解决方案,一个关键的成功因素是保持用户模型和相关逻辑尽可能独立于用于验证用户的机制:保持独立的解决方案也有助于以这种方式思考.
从用户的角度来看,通过第二个提供者登录却发现他们有 none 以前的内容可能会让人感到非常困惑和不安。从这个角度来看,我认为合并将是最好的最终目标。
现在从技术角度来看,我对此有所了解,发现这很麻烦。当用户首先使用电子邮件登录然后使用社交媒体登录时,我设法合并了身份,但反之则不然。我想唯一的选择是有一个 pre-signup lambda 触发器来检查数据库中该特定电子邮件的先前登录,并要求用户也登录这些电子邮件以进行合并或只是继续登录现有的。如果不止一个 pre-existing 登录,这说起来容易做起来难。
关于谁“赢得”合并的问题,总是pre-existing。最后也没有关系,因为所有登录都将通过调用使用相同的 Cognito 联合 ID。