所以我有多个网站运行一个代码库(asp.net标准MVC(。我使用内置的ASPNet.Identity方法供用户注册/登录(使用ApplicationSignInManager、ApplicationUserManager(。
目前,所有网站都使用一个数据库来存储用户信息。这导致了几个问题:
-
当用户A在网站A上注册时,他们现在可以使用相同的详细信息登录网站B。据他们所知,他们没有在B网站上注册。不好!
-
如果我限制用户A只能访问网站A,如果该用户随后试图在网站B上注册,他们会收到"电子邮件地址已在使用"错误。也不好!
我尝试过将数据库分离,每个站点一个,以解决这个问题,但我不知道如何动态更改分配给控制器中ApplicationSignInManager和ApplicationUserManager的DBContext。
例如,当用户来到网站a时,我获取网站a的连接字符串并执行登录/注册操作。我需要域名来确定要加载哪个连接字符串,在startup.cs代码运行并配置我的管理器实例之前,我无法访问该连接字符串。
我想肯定是其他人干的。理想情况下,我需要在Startup.cs运行后动态更改DBContext。如果做不到这一点,我需要一种很好的方法来将多个相同的电子邮件地址存储在同一个DB 中
感谢
如果你在当前上下文所在的网站上有一个标志,我认为最容易实现的是做两件事:
- 用一个Website属性扩展IdentityUser,这个属性很简单,要么是int WebsiteId,要么是String
- 扩展AccountController以在任何需要的地方使用该属性,我认为您需要修改"注册"和所有"登录"功能来验证帐户所在的网站
我设法找到了一个解决方案。它不是最优雅的,但它解决了这个问题,直到我能够弄清楚如何动态更改登录/注册期间使用的DB上下文
在IdentityConfig.cs中,我将"RequireUniqueEmail"切换为false:
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = false
};
然后,当用户注册时,我会获取电子邮件地址,使其成为他们注册的网站的唯一地址,并将其存储在UserName字段中(我不会将UserName用于任何用途(。当他们登录时,我会在尝试登录之前对输入的电子邮件地址进行相同的更改。
如果该用户在不同的网站上注册,即使电子邮件相同,用户名也会不同。虽然不完美,但它很管用。
例如
string uniqueCode = "Website_Specific_String";
var user = new ApplicationUser { uniqueCode + model.Email, Email = model.Email};
var result = await UserManager.CreateAsync(user, model.Password);
和登录
var user = await UserManager.FindByNameAsync(uniqueCode + model.Email);
仍然对更好的想法持开放态度。感谢