C# Individual User Accounts多竞赛场景:子域名用户绑定与登录验证及用户名问题
问题解答
一、登录页面验证用户所属竞赛的实现方案
解析子域名对应的竞赛ID
从当前请求的Host中提取子域名,比如请求地址是comp1.yourdomain.com,拆分出子域名comp1后,查询竞赛表获取对应的CompID(建议给竞赛表新增SubDomain字段,用子域名直接匹配比用Name更可靠)。
后台示例代码:string host = Request.Url.Host; string subDomain = host.Split('.')[0]; // 根据实际域名结构调整拆分逻辑 var competition = db.Competitions.FirstOrDefault(c => c.SubDomain == subDomain); if (competition == null) { ErrorMessage.Text = "当前子域名无效"; return; } int currentCompId = competition.ID;登录时额外校验用户所属竞赛
验证用户名密码通过后,对比用户的CompID与当前子域名对应的竞赛ID:var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db)); var user = await userManager.FindAsync(UserName.Text, Password.Text); if (user != null) { if (user.CompID == currentCompId) { // 校验通过,执行登录逻辑 await SignInAsync(user, RememberMe.Checked); Response.Redirect("~/Default.aspx"); } else { ErrorMessage.Text = "该用户不属于当前竞赛"; } } else { ErrorMessage.Text = "用户名或密码错误"; }
二、同一用户名跨竞赛注册的问题
默认情况下,ASP.NET Identity的AspNetUsers表中UserName字段是全局唯一索引,直接用默认注册逻辑的话,同一用户名注册到不同竞赛会因重复报错。
要实现同一用户名可跨竞赛注册,需做两处修改:
- 修改数据库唯一约束
将AspNetUsers表的唯一索引从单独的UserName,改为(UserName, CompID)的复合唯一索引,确保同一用户名仅在同一竞赛内唯一。 - 自定义用户验证逻辑
重写UserValidator,让它仅检查当前竞赛内的用户名是否重复:
然后在UserManager配置中替换默认验证器:public class CustomUserValidator : UserValidator<ApplicationUser> { private readonly ApplicationDbContext _dbContext; public CustomUserValidator(UserManager<ApplicationUser> manager, ApplicationDbContext dbContext) : base(manager) { _dbContext = dbContext; } public override async Task<IdentityResult> ValidateAsync(ApplicationUser user) { var result = await base.ValidateAsync(user); var existingUser = _dbContext.Users.FirstOrDefault(u => u.UserName == user.UserName && u.CompID == user.CompID); if (existingUser != null && existingUser.Id != user.Id) { result.Errors.Add("该用户名在当前竞赛中已存在"); } return result; } }public class ApplicationUserManager : UserManager<ApplicationUser> { public ApplicationUserManager(IUserStore<ApplicationUser> store) : base(store) { this.UserValidator = new CustomUserValidator(this, new ApplicationDbContext()); } }
完成上述修改后,同一用户名即可在不同竞赛下注册。
内容的提问来源于stack exchange,提问作者Talan
相关产品推荐
相关产品推荐

