Поддержка входа с электронной почтой или именем пользователя для того же пользователя в ASP.NET Core - PullRequest
0 голосов
/ 12 июня 2018

Я использую ASP.NET Core Identity (2.0) со всем кодом по умолчанию.Я изменил метод AccountController.Login, чтобы проверить устаревшую базу данных и перенести пользователей, когда пользователь не найден.Поскольку в этой старой базе данных были имена пользователей и адреса электронной почты, я заполняю оба поля во вновь созданном пользователе.

Но тогда, если я попытаюсь снова войти в систему с перенесенным пользователем, использование электронной почты не работает, как кажется, SQL-запрос всегда ищет только WHERE u.NormalizedUserName = @__normalizedUserName_0.

Как я могу разрешить одному пользователю с адресом электронной почты и именем пользователя, которые отличаются, войти в систему либо с помощью своего имени пользователя, либо своего адреса электронной почты?

Ответы [ 3 ]

0 голосов
/ 13 июня 2018

Спасибо всем участникам, но я думаю, что этот вопрос заслуживает более точного ответа.

Шаблоны по умолчанию для ASP.NET Core Identity всегда будут создавать пользователей с электронной почтой и именем пользователя, содержащими одно и то же значение.Затем обработчик входа по умолчанию (либо в AccountController.Login, либо в методе OnPostAsync представления «Вход в систему») всегда использует поле «email» в качестве имени пользователя и вызывает PasswordSignInAsync.Хотя код, кажется, подразумевает, что он поддерживает электронную почту, этот метод действительно принимает только имя пользователя.Чтобы добавить в заблуждение, представление делает проверку того, что вы ввели действительный адрес электронной почты, но то, что вы вводите, в конечном итоге будет найдено в поле NormalizedUserName!

Таким образом, если вы также хотите разрешить электронную почтуКак заявили Марк и Разван, вы можете использовать _userManager.FindByEmailAsync, чтобы получить действительное имя пользователя, пытающегося войти в систему, а затем вызвать PasswordSignInAsync с именем пользователя.

Как , заявленное Барри Доррансом: «Нет, вы правы. Шаблоны заканчиваются тем, что имя пользователя и адрес электронной почты совпадают при регистрации, но не в состоянии синхронизировать их. В 2.2 запланирована работа по устранению этого уродливого беспорядка».

открытый номер здесь .

0 голосов
/ 06 июля 2018
  1. Вы должны изменить AccountViewModel.cs

    public class LoginViewModel
        {
            [Required]
            [Display(Name = "Логин/Email")]
            //[EmailAddress]
            public string Email { get; set; }
    
            [Required]
            [DataType(DataType.Password)]
            [Display(Name = "Пароль")]
            public string Password { get; set; }
    
            [Display(Name = "Запомнить меня")]
            public bool RememberMe { get; set; }
        }
    
  2. AccountController.cs

    
    public async Task Login(LoginViewModel model, string returnUrl)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }</p>
    
        ApplicationUser user;
        if (model.Email.Contains("@"))
            user = UserManager.FindByEmail(model.Email);            
        else
            user = UserManager.FindByName(model.Email);
    
        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);
        }
    }
    
0 голосов
/ 13 июня 2018

У вас есть возможность использовать метод CheckPasswordAsync(user, password) из UserManager: https://github.com/aspnet/Identity/blob/a273e349eea2be3a40b16e6947b2deab95f4b5b2/src/Core/UserManager.cs#L692

Прямо перед вызовом этого метода вы можете вызвать своего пользователя следующим образом:

 var user = await _userManager.FindByNameAsync(userName) ?? await _userManager.FindByEmailAsync(userName);

Исходя из вашей текущей реализации UserStore, вам может потребоваться настроить FindByNameAsync или FindByEmailAsync или оба.

...