允许用户使用电子邮件或用户名(AspNet.Identity)登录

本文关键字:用户 AspNet Identity 登录 许用户 电子邮件 | 更新日期: 2023-09-27 18:24:13

我想知道这里是否有更有效的路线。使用AspNet.Identity,我希望允许用户使用他们的UserNameEmail登录到同一文本框。我继续在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;
    }
}

我的担忧有两个方面:

  1. 他们是一种更有效、更实用的方法吗
  2. 通过这种方式,我是否引入了任何新的安全风险或性能风险

我在下面附上了整个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

允许用户使用电子邮件或用户名(AspNet.Identity)登录

将出现一个安全问题。如果你知道另一个用户的电子邮件,你可以获得他的用户名:

  1. 写他的电子邮件和错误的密码
  2. 然后,系统加载相应的用户名,执行失败的密码验证,并返回带有覆盖用户名的模型

我会声明新的变量而不是模型。用户名重用。如果你使用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);