好的,我有一个网站,您可以自己注册并登录。您也可以使用您的Facebook,Twitter或linkedin帐户登录。
重要的是,用户只能注册一个帐户。所以不知何故,我想合并用户的帐户,如果他们使用不同的方法登录。解决这个问题的最佳解决方案是什么?
例如,用户使用他的Facebook帐户登录。我使用这些数据自动为他注册一个帐户。我应该发送一封包含我们网站用户名和密码的电子邮件吗? (如果Facebook的政策没有问题)。我应该给他们第二个屏幕,他们可以填写用户名和密码吗?但这并不是使用您的Facebook帐户登录的理念。它应该简化您的参与程序。
用户也可以在我们的网站上注册,并在下次使用他的Twitter帐户登录时。如何将这两个帐户合并为一个?什么是最好的方式?
基本上我的问题是:我有4种不同的方式让用户成为我们网站的成员。如果用户决定使用多种方式,我如何确保所有这4种方式只创建一个帐户?什么是最好的流程,以确保它不会成为用户自己的麻烦?
编辑:
在我提出这个问题3年后,我在一系列文章中给出了答案:http://www.sitepoint.com/series/using-social-networks-as-a-login-system/
答案 0 :(得分:117)
我现在面临着完全相同的任务。我设计的设计相当简单,但效果很好。
核心思想是本地站点标识和第三方站点标识的模型保持隔离,但后来链接。因此,登录该站点的每个用户都具有映射到任意数量的第三方站点身份的本地身份。
本地身份记录包含最少的信息 - 它甚至可以是单个字段 - 只是一个主键。 (对于我的申请,我不关心用户的电子邮件,姓名或出生日期 - 我只是想知道他们一直是登录此帐户的人。)
第三方身份包含仅与第三方身份验证相关的信息。对于OAuth,这通常表示用户标识符(如id,电子邮件或用户名)和服务标识符(指示通过身份验证的站点或服务)。在应用程序的其他部分中,在数据库之外,该服务标识符与用于从该服务检索相关用户标识符的方法配对,并且这是如何执行认证的。对于OpenID,我们采用相同的方法,除了认证方法更通用(因为我们几乎总能执行完全相同的协议 - 除了我们使用不同的身份URL,这是我们的服务标识符)。
最后,我会记录哪些第三方身份与当地身份配对。要生成这些记录,流程如下所示:
合并帐户是合并本地身份的每个单独字段的问题(根据应用程序的不同而不同,如果您的本地身份记录中只有几个字段,则应该很容易),然后确保链接的第三个字段 - 身份认同与产生的本地身份相关联。
答案 1 :(得分:42)
我倾向于发现很多基于电子邮件的网站合并为重叠加入因素。
我可以看到这是一个可行的选择,但这又取决于你对如何合并的偏好。电子邮件地址是人们用来验证网站上一些重要信息变更的主要方式,例如更改密码,终止服务,帐户余额等等......这几乎就像网络的社会安全号码系统但具有通信能力。文化上:我认为假设电子邮件在OAuth身份验证服务中是一个非常独特的身份是合理的。当然,这就是Facebook和Google要求的登录表单。
我目前的思考过程。
登录页面有3个选项
1)首次用户登录:触发注册流程,首次创建和填充帐户。
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 ]
2)在其他时间,用户回来但决定点击Google登录
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" ]
3)现在,您已经合并了您信任的帐户,数据库条目上的电子邮件与您从外部登录信任的电子邮件相同。
因此对于后续登录
那么,如果您首先拥有外部登录,然后您希望用户以后能够使用密码登录,该怎么办?
我认为有两种简单的方法可以做到这一点
在从外部身份验证创建帐户时首次登录时,请他们输入密码以完成首次进入您的应用程序
如果他们已经使用Facebook或谷歌首先注册,那么不知何故想要使用您自己网站的注册表注册。检测他们输入的电子邮件地址是否已存在,询问他们是否有密码,并在注册完成后向他们发送电子邮件确认。
答案 2 :(得分:34)
答案 3 :(得分:21)
自动合并帐户的这两种方法都留下了相当大的漏洞,允许某人接管帐户。他们似乎都假设用户是他们在向注册用户提供合并选项时所说的用户。
我对减轻漏洞的建议是在执行合并之前请求用户与其中一个已知的身份提供商进行身份验证,以验证用户的身份。
示例:用户A注册Facebook身份。稍后他们会返回您的站点并尝试使用Windows Live ID访问并开始注册过程。您的网站将提示用户A ...看起来您之前已在Facebook注册过。请使用Facebook登录(提供链接),我们可以将您的Windows Live ID与现有配置文件合并。
另一种方法是在合并身份时用户必须提供的初始注册中存储共享密钥(密码/个人问题),但这会让您重新进入存储共享机密的业务。这也意味着您必须处理用户不记得共享密钥及其随附的工作流程的情况。
答案 4 :(得分:0)
上面有很好的答案和资源。我的贡献总结在这里...... https://github.com/JavascriptMick/learntree.org/blob/master/design/Schema.md
TLDR:单独的帐户和人员架构。帐户,电子邮件和OAuth的2种变体。
帐户-authenticates->人
答案 5 :(得分:-4)
您应该允许从一个帐户登录,然后在登录时提供添加其他帐户以与其合并的选项。