允许用户使用电子邮件或用户名(AspNet.Identity)登录
本文关键字:用户 AspNet Identity 登录 许用户 电子邮件 | 更新日期: 2023-09-27 18:24:13
我想知道这里是否有更有效的路线。使用AspNet.Identity
,我希望允许用户使用他们的UserName
或Email
登录到同一文本框。我继续在AccountController Login ActionResult
中讨论了这个问题。我在打电话之前进行了检查:
var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: true);
检查:
//TODO: determine if there is a more efficient way to allow user to login either with Email || UserName
if (model.UserName.Contains("@"))
{
using (var context = new ApplicationDbContext())
{
model.UserName = (context.Users.Any(p => p.Email == model.UserName)) ?
context.Users.SingleOrDefault(p => p.Email == model.UserName).UserName :
model.UserName;
}
}
我的担忧有两个方面:
- 他们是一种更有效、更实用的方法吗
- 通过这种方式,我是否引入了任何新的安全风险或性能风险
我在下面附上了整个
ActionResult
供参考。
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
//TODO: determine if there is a more efficient way to allow user to login either with Email || UserName
if (model.UserName.Contains("@"))
{
using (var context = new ApplicationDbContext())
{
model.UserName = (context.Users.Any(p => p.Email == model.UserName)) ?
context.Users.SingleOrDefault(p => p.Email == model.UserName).UserName :
model.UserName;
}
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: true);
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("", "Invalid login attempt.");
return View(model);
}
}
相关github问题#2和#4
将出现一个安全问题。如果你知道另一个用户的电子邮件,你可以获得他的用户名:
- 写他的电子邮件和错误的密码
- 然后,系统加载相应的用户名,执行失败的密码验证,并返回带有覆盖用户名的模型
我会声明新的变量而不是模型。用户名重用。如果你使用FirstOrDefault:,你的查询会更有效
var userName = model.UserName;
using (var context = new ApplicationDbContext())
{
var user = context.Users.FirstOrDefault(p => p.Email == model.UserName);
if (user != null)
{
userName = user.UserName;
}
}
var result = await SignInManager.PasswordSignInAsync(userName, model.Password, model.RememberMe, shouldLockout: true);