Asp.Net Core 2.0如何配置登录支持邮箱或用户名登录?
配置ASP.NET MVC支持邮箱或同时支持邮箱/用户名登录
咱们先理清问题根源:默认的ASP.NET Identity登录逻辑只认用户名,所以得修改验证逻辑,让它能识别邮箱,或者同时兼容两种登录方式。下面分两种场景一步步操作:
一、仅支持邮箱登录
如果只想让用户用邮箱登录,操作很直接:
调整前端登录视图
打开Views/Account/Login.cshtml,把输入框的标签和提示改成邮箱相关内容,同时更新绑定的模型字段:<div class="form-group"> @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.Email, new { @class = "form-control", placeholder = "输入你的登录邮箱" }) @Html.ValidationMessageFor(m => m.Email) </div> </div>记得同步更新
LoginViewModel,把原来的UserName字段换成Email,并加上必要的验证特性。修改后端登录验证逻辑
在AccountController的LoginPOST方法里,替换默认的用户名查找逻辑,改用邮箱定位用户:[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (!ModelState.IsValid) { return View(model); } // 通过邮箱查找用户 var user = await UserManager.FindByEmailAsync(model.Email); if (user != null) { // 用找到的用户的用户名完成登录验证 var result = await SignInManager.PasswordSignInAsync(user.UserName, model.Password, model.RememberMe, shouldLockout: false); switch (result) { case SignInStatus.Success: return RedirectToLocal(returnUrl); case SignInStatus.LockedOut: return View("Lockout"); case SignInStatus.RequiresVerification: return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); case SignInStatus.Failure: default: ModelState.AddModelError("", "无效的登录尝试,请检查邮箱和密码。"); return View(model); } } ModelState.AddModelError("", "未找到该邮箱对应的用户。"); return View(model); }
二、同时支持用户名和邮箱登录(更优方案)
这个方案会自动判断用户输入的是邮箱还是用户名,然后对应验证,步骤如下:
更新前端登录视图
修改Login.cshtml,把输入框提示改成“用户名或邮箱”,让用户明确两种方式都可用:<div class="form-group"> @Html.LabelFor(m => m.LoginInput, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.LoginInput, new { @class = "form-control", placeholder = "输入用户名或邮箱" }) @Html.ValidationMessageFor(m => m.LoginInput) </div> </div>同步更新
LoginViewModel,新增LoginInput字段替换原来的UserName/Email:public class LoginViewModel { [Required] [Display(Name = "用户名或邮箱")] public string LoginInput { get; set; } [Required] [DataType(DataType.Password)] [Display(Name = "密码")] public string Password { get; set; } [Display(Name = "记住我?")] public bool RememberMe { get; set; } }修改后端验证逻辑
在AccountController的LoginPOST方法里,添加格式判断:先检查输入是否符合邮箱格式,是则用邮箱找用户,否则用用户名查找:[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (!ModelState.IsValid) { return View(model); } // 判断输入是否为邮箱格式 bool isEmail = Regex.IsMatch(model.LoginInput, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"); ApplicationUser user = null; if (isEmail) { user = await UserManager.FindByEmailAsync(model.LoginInput); } else { user = await UserManager.FindByNameAsync(model.LoginInput); } if (user != null) { var result = await SignInManager.PasswordSignInAsync(user.UserName, model.Password, model.RememberMe, shouldLockout: false); switch (result) { case SignInStatus.Success: return RedirectToLocal(returnUrl); case SignInStatus.LockedOut: return View("Lockout"); case SignInStatus.RequiresVerification: return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); case SignInStatus.Failure: default: ModelState.AddModelError("", "密码错误,请重试。"); return View(model); } } ModelState.AddModelError("", "未找到该用户名或邮箱对应的用户。"); return View(model); }额外注意事项
- 确保
ApplicationUser类的Email字段是唯一且必填的,避免出现多个用户共用一个邮箱的情况; - 如果是ASP.NET Core版本的Identity,核心逻辑一致,只是
SignInManager和UserManager的调用方式略有差异,核心还是判断输入类型并查找用户。
- 确保
内容的提问来源于stack exchange,提问作者Praveen Rai
相关产品推荐
相关产品推荐

