我已经通过sled.com进行了此操作。在创建帐户和支持多个第三方帐户登录方面,这里存在多个问题。他们之中有一些是:
对于sled.com,我决定删除本地密码,因为它增加了很小的价值,并且增加了保护密码输入表单的额外成本。有许多已知的破坏密码的攻击,如果要引入密码,则必须确保它们不容易破解。您还需要将它们存储在单向哈希或类似方式中,以防止它们泄漏。
听起来您已经选择了三个登录提供程序:Facebook,Twitter和LinkedIn。太好了,因为这意味着您正在使用OAuth,并且正在使用一组定义明确的受信任的提供程序。我不喜欢OpenID。剩下的问题是您是否需要支持来自同一提供商的多个第三方帐户(例如,一个具有两个Twitter帐户链接的本地帐户)。我假设没有,但是如果您这样做,则需要在数据模型中进行调整。
对于Sled,我们支持使用Facebook,Twitter和Yahoo!登录。并且在每个用户帐户中存储每个密钥:{“ _id”:“ djdjd99dj”,“ yahoo”:“ dj39djdj”,twitter:“ 3723828732”,“ facebook”:“ 12837287”}。我们设置了一堆约束,以确保每个第三方帐户只能链接到一个本地帐户。
如果要允许来自同一第三方提供商的多个帐户,则需要使用列表或其他结构来支持该功能,并使用所有其他限制来确保唯一性。
用户首次注册您的服务时,他们会先去找第三方提供商,然后返回经过验证的第三方ID。然后,您可以为他们创建一个本地帐户,并收集所需的任何其他信息。我们收集他们的电子邮件地址,并要求他们选择一个本地用户名(我们尝试使用其他提供商的现有用户名预先填充表格)。拥有某种形式的本地标识符(电子邮件,用户名)对于以后恢复帐户非常重要。
如果浏览器没有用于现有帐户的会话cookie(有效或已过期),并且未找到所使用的第三方帐户,则服务器会知道这是首次登录。我们试图通知用户,他们不仅是在登录,而且还在创建一个新帐户,这样,如果他们已经有一个帐户,他们希望将暂停并使用现有帐户登录。
我们使用完全相同的流程来链接其他帐户,但是当用户从第三方回来时,将使用有效的会话cookie来区分将新帐户链接到登录操作的尝试。我们仅允许每种类型的一个第三方帐户,如果已经有一个关联的帐户,请阻止该操作。这应该不成问题,因为如果已经有一个(每个提供者)一个帐户,则链接新帐户的接口将被禁用,但以防万一。
如果用户尝试链接已经链接到本地帐户的新第三方帐户,则只需提示他们确认要合并这两个帐户(假设您可以使用数据集处理此类合并-通常更容易地说比完成)。您还可以为他们提供一个特殊的按钮来请求合并,但是实际上,他们所做的只是链接另一个帐户。
这是一个非常简单的状态机。用户使用第三方帐户ID从第三方回来。您的数据库可以处于以下三种状态之一:
- 该帐户已链接到本地帐户,并且没有会话cookie->登录
- 该帐户已链接到本地帐户,并且存在会话cookie->合并
- 该帐户未链接到本地帐户,并且没有会话cookie->注册
该帐户未链接到本地帐户,并且存在会话cookie->链接其他帐户
这仍然是实验领域。我还没有看到完美的UX,因为大多数服务都在第三方帐户旁边提供了本地密码,因此着眼于“忘记密码”用例,而不是其他所有可能出错的地方。
对于Sled,我们选择使用“需要帮助登录吗?” 当您单击时,询问用户其电子邮件或用户名。我们会查找它,如果找到匹配的帐户,请给该用户发送电子邮件链接,该链接可以自动将其登录到该服务(一次有效)。进入后,我们将他们直接带到帐户链接页面,告诉他们应该看一下并可能链接其他帐户,并向他们显示他们已链接的第三方帐户。