Architecture 用于将多个用户帐户合并在一起的体系结构

Architecture 用于将多个用户帐户合并在一起的体系结构,architecture,oauth,openid,multiple-login,Architecture,Oauth,Openid,Multiple Login,好的,我有一个网站,你可以注册并登录。您也可以使用您的facebook、twitter或linkedin帐户登录 重要的是,用户只能注册一个帐户。因此,如果用户使用不同的方法登录,我想合并他们的帐户。解决这个问题的最佳解决方案是什么 例如,用户使用其Facebook帐户登录。我用这些数据为他自动注册了一个账户。我应该发送一封包含我们网站用户名和密码的电子邮件吗?(如果这符合Facebook的政策)。我应该给他们第二个屏幕,让他们填写用户名和密码吗?但这并不是用你的Facebook帐户登录的想法。

好的,我有一个网站,你可以注册并登录。您也可以使用您的facebook、twitter或linkedin帐户登录

重要的是,用户只能注册一个帐户。因此,如果用户使用不同的方法登录,我想合并他们的帐户。解决这个问题的最佳解决方案是什么

例如,用户使用其Facebook帐户登录。我用这些数据为他自动注册了一个账户。我应该发送一封包含我们网站用户名和密码的电子邮件吗?(如果这符合Facebook的政策)。我应该给他们第二个屏幕,让他们填写用户名和密码吗?但这并不是用你的Facebook帐户登录的想法。它应该简化您的参与程序

用户也有可能在我们的网站上注册了自己,下一次使用他的twitter帐户登录时。如何将这两个帐户合并为一个?最好的办法是什么

所以基本上我的问题是:我有4种不同的方式让用户成为我们网站的一员。如果用户决定使用多种方式,我如何确保这四种方式只创建一个帐户?确保它不会成为用户自己的麻烦的最佳流程是什么


编辑:

在我提出这个问题3年后,我自己在一系列文章中给出了答案:



您应该允许从一个帐户登录,然后在登录时提供添加其他不同帐户以与之合并的选项。

我目前面临着完全相同的任务。我设计的设计很简单,但效果很好

其核心思想是,本地站点标识和第三方站点标识的模型保持隔离,但稍后会链接起来。因此,登录到站点的每个用户都有一个本地标识,该标识映射到任意数量的第三方站点标识

本地身份记录只包含一个主键,它包含的信息最少,甚至可以是单个字段。(对于我的应用程序,我不关心用户的电子邮件、姓名或出生日期-我只想知道他们就是一直登录此帐户的人。)

第三方身份包含仅与第三方身份验证相关的信息。对于OAuth,这通常意味着一个用户标识符(如id、电子邮件或用户名)和一个服务标识符(指示使用哪个站点或服务进行身份验证)。在应用程序的其他部分中,在数据库之外,该服务标识符与用于从该服务检索相关用户标识符的方法配对,这就是执行身份验证的方式。对于OpenID,我们采用了相同的方法,只是认证的方法更加通用(因为我们几乎可以执行完全相同的协议-除了使用不同的标识URL,这是我们的服务标识符)

最后,我记录了哪些第三方身份与哪些本地身份配对。要生成这些记录,流程如下所示:

  • 用户首次使用第三方身份登录。创建本地标识记录,然后创建第三方标识记录,然后将它们配对
  • 在控制面板中,用户可以通过登录第三方服务链接帐户。(其工作原理非常简单。)
  • 在用户无意中创建多个帐户的场景中,解决方案非常简单。当用户登录其中一个帐户时,他会登录到另一个以前用于登录站点的帐户(通过上面的控制面板功能)。web服务检测到此冲突(已登录用户的本地标识与链接到刚登录的第三方标识的本地标识不同),并提示用户进行帐户合并

合并帐户是一个合并本地身份的每个单独字段的问题(在不同的应用程序中会有所不同,如果您的本地身份记录中只有几个字段,这应该很容易),然后确保链接的第三方身份与生成的本地身份相链接。

我已经通过sled.com了解了这一点。关于创建帐户和支持多个第三方帐户进行登录,这里存在多个问题。其中包括:

  • 您需要同时支持本地密码和第三方登录吗
对于sled.com,我决定删除本地密码,因为它增加的值很小,并且在保护密码输入表单时需要额外的成本。有许多已知的破解密码的攻击,如果你要引入密码,你必须确保它们不容易破解。您还需要将它们存储在单向散列或类似的方式中,以防止它们被泄漏

  • 在支持多个第三方帐户时,您希望有多大的灵活性
听起来你已经选择了三个登录提供商:Facebook、Twitter和LinkedIn。这很好,因为这意味着您正在使用OAuth并使用一组定义良好的可信提供者。我不喜欢OpenID。剩下的问题是,您是否需要支持来自同一提供商的多个第三方帐户(例如,一个本地帐户与两个Twitter帐户链接)。我假设不是,但是如果你这样做了,你需要在你的数据模型中考虑到这一点

对于Sled,我们支持使用Facebook、Twitter和Yahoo!在每个用户帐户中为每个帐户存储一个密钥:{“_id”:“djd99dj”,“yahoo”:“dj39djdj”,twitter:“3723828732”,“facebook:“12837287”}。我们设置了一系列约束,以确保每个第三方帐户只能链接到单个本地帐户

如果要允许来自同一第三方提供商的多个帐户,则需要
 if the user logins using Facebook (or whatever 3rd party login)
      1) call the Facebook api asking for their information (email, name, etc...) 
      2) create an account membership entry in your database somewhat like this 

         Table = Users
         [ UserId   |       Email             | Password ]
         [    23     | "newuser@coolmail.com" |  *null*  ]

      3) create an external auths entry like so
         *ProviderUserId is the unique id of that user on the provider's site

         Table = ExternalAuths
         [ ExternalAuthId  |  User_UserId   | ProviderName |   ProviderUserId  ]
         [    56           |      23        |   Facebook   |  "max.alexander.9"]

 if the user wants to create an account with your own registration it would just be this           

         Table = Users
         [ UserId   |       Email           |   Password  ]
         [    23     | newuser@coolmail.com |  myCoolPwd  ]
      1) call the Google api asking for their information (email, name, etc...) 

      2) once you get the email, match it up to the userId entry with the existing email 

      3) create an additional External auth entry as such

         Table = ExternalAuths
         [ ExternalAuthId  |  User_UserId   | ProviderName |   ProviderUserId  ]
         [    56           |      23        |   Facebook   |  "max.alexander.9"]
         [    57           |      23        |    Google    |  "1234854368"     ]