如何允许通过多个身份验证提供程序进行注册,同时共享相同的电子邮件地址?

时间:2014-04-30 13:07:21

标签: authentication oauth

这可能是SO和UX.se之间的一个问题。

我正在实施一个注册/登录系统,它允许多种身份验证方式:使用Facebook,Twitter,Github和本地(用户名+密码)注册的社交注册。

在后端,我有一个User模型和一个Passport模型。 User可能有多个Passports,这意味着User可以通过不同的方式进行身份验证(例如:通过本地登录,或通过Facebook等)

好的衡量标准:特定Passports的{​​{1}}将始终来自其他提供商(facebook,twitter,local)。即:Facebook护照,本地护照等。

这似乎是一种很好的方式,并且允许我将User连接到多种身份验证方式。

我熟悉这可能带来的安全问题,因此要合并/合并护照,用户必须登录到两者。

好的问题。请考虑以下流程:

  1. user-a通过电子邮件user-a@gmail.com
  2. 注册提供商,例如本地用户
  3. user-a签出(或者它的会话已过期)。
  4. 用户 - 使用其他提供商登录,比如说facebook。有可能是facebook帐户的电子邮件记录为user-a@gmail.com
  5. 目前,我已将User account定义为email模型中的唯一身份。这意味着上述注册将失败,因为已经有User,通过本地Passport,具有所提到的电子邮件地址。

    在这种情况下,什么是最佳做法?我相信必须有很多实现浮动,必须看到这个问题弹出。

    选项:

    1. 警告用户身份验证是否可能,并通过其他身份验证机制向用户提及当前电子邮件地址已经注册?这将是合理的用户友好性。
    2. 请注意,通过不同的提供商存在的用户帐户具有相同的电子邮件地址,因此将新的Passport与用户合并。。我只是把它放在一个很好的衡量标准中:这是一个非常大的攻击向量,允许用户-b通过伪造电子邮件地址(通过不做电子邮件的社交提供商)访问帐户 - 验证)
    3. User-account上没有唯一性限制,但在<user,email>上。这样就可以创建新的<passport, email>和关联的User,并且一切顺利。现在,同一个真实的人可能有2个用户帐户:每个身份验证提供商1个。作为下一阶段,允许合并用户帐户,登录到两者并确认合并。
    4. 我倾向于3,但1更简单。我不确定,您怎么看? 你以前遇到过这个吗?

1 个答案:

答案 0 :(得分:3)

是的,#3。我自己实现了这个。您正在考虑的概念是:关联多个SSO帐户。我的用户结构如下:

name : { 
    first:  { type: String},
    last:   { type: String }
},
emails: [{ type: String, unique: true, 'index': true }],  //all known emails as provided by SSO services. we use this to cross ref when the user uses a different SSO to login after initial setup. this avoids account dupes
sso: [{
    provider:   { type: String, required: true}, //matches the name of passport strategy name employed
    userid:     { type: String, required: true } //the specific SSO provider userID that's unique in the provider's realm
}]

因此,在您的身份验证序列中,您通过电子邮件或提供商+用户ID组合查找,如果您没有找到SSO提供商,请附加它。或者某人可能更新其电子邮件但特定SSO提供商ID的原因永远不会改变。

另一种常见做法(如果在您的应用中有意义)是允许用户“链接”SSO帐户。这允许您处理不同的电子邮件地址。示例:用户FB电子邮件是个人电子邮件,但在LinkedIn中,他列为主要电子邮件。 LinkedIn遗憾地通过他们的OAuth2电话为您提供主要服务。