我这样做的方法是保留分开的第三方登录详细信息,并使用可互换的电子邮件和第三方登录详细信息等表格来验证用户身份。通过这种方式,您可以让客户通过使用电子邮件或使用第三方登录获得授权。这并不意味着同一用户可以使用电子邮件和密码或第三方提供商登录。我发现这有助于避免在 User 表中包含第三方提供商的所有时间字段,如果您想添加更多登录提供商,您不必更改任何表,只需在 Types 表中添加另一个条目。
例如,我将使用用户表,您可以在其中保留客户的所有详细信息,但登录详细信息。没有电子邮件、密码或任何其他登录详细信息。这些详细信息保存在单独的表格中,并由该表格中的 PK 链接。此表将 1:1 映射到电子邮件表。例如,架构可能是:
- Id (PK)
- FirstName
- SecondName
- etc.
然后我将有一个电子邮件表,我将在其中保存用户的电子邮件和密码。您还可以获得额外的详细信息,例如 ID 和已验证(以了解电子邮件是否已验证)。请注意在您的数据库中保留纯文本密码或保留对电子邮件 - 密码。这是一个重要的安全问题,我不会在这里讨论。我还将使用 UserId 列将电子邮件映射到用户。这将 1:1 映射到用户表。架构可能是:
- Id (PK)
- Email
- Password
- UserId (FK)
- Verified
为了处理第三方登录详细信息,我将使用一个名为ThirdPartyUsers的表。在此表中,我将存储一个 UserId 以将该表中的一条记录映射到用户表中的一条记录。基本上这个表可以替换电子邮件表,你可以远离在你的数据库中保存电子邮件-密码。在此表中,我将保留一个 ProviderCode,它是 types 表中的代码,以及一个 ProviderId,它是第三方登录提供的 Id。此 ID 对于每个第三方提供商都是唯一的,并且不会因用户而改变。您可以将 ProviderCode 与 ProviderId 配对以创建复合键。这将 1:1 映射到用户表。架构可能是:
- Id (PK)
- UserId (FK)
- ProviderCode
- ProviderId
要拥有一个统一的用户帐户,我将有一个MasterUsers表,您可以在其中将 User 定义为 Master 用户,并将其子项定义到链接表中。通过它的孩子,我了解任何具有相同电子邮件地址的帐户。这意味着经典帐户和任何第三方登录提供商。使用它,您可以拥有一个独特的大师和多个孩子。这会将 1:1 映射到 Users 表,并将 1:* 映射到 MasterLinkToChildren 表。架构可能是:
- Id (PK)
- UserId
要将多个客户链接到一个 MasterUser,我将使用一个名为 MasterLinkToChildren(或您喜欢的任何命名)的链接表。在此,我将有两列用于存储孩子的 UserIds 和为其父母的 MasterId。我要做的一件重要的事情是让任何 MasterUser 也成为 Link 表中他自己的孩子,因此当您更新 MasterUser 时,您将保持记录之间的一致性。这会将 *:1 映射到 MasterUsers 和 1:1 到 Users 表。架构可能是:
- MasterId (FK)
- UserId (FK)
最后,我将有一个Codes表,我将在其中存储每个第三方登录提供程序的唯一代码。这会将 1:* 映射到 ThirdPartyUsers。像这样的架构:
- Id (PK)
- Code (Unique)
它可能看起来像很多代码和很多表,但通过这种方式,您可以保留唯一的用户登录,或者您可以将所有内容统一在一个主帐户下。我不会自动合并它们,但我会为用户提供这样做的选项。您需要考虑的另一件事是不允许用户在验证其帐户之前登录或合并帐户。我没有在 ThirdPartyUsers 表上使用 Verified 列,因为我不想验证这种类型的用户,但您也可以这样做。
通过使用 Codes 表,您可以扩展您的第三方登录提供程序,而无需更改其他表。