Identity 2.0无效的登录尝试

igg*_*web 7 c# asp.net-mvc-5 asp.net-identity-2

出于某种原因,我还没有发现,但在注册和激活成功后,我无法使用电子邮件地址登录,而是收到错误"无效登录尝试".

由于使用电子邮件登录改进了ASP.NET Identity 2.0,我已经修改了注册表单以实际存储真实用户名,因为现有注册似乎通过将Username与电子邮件地址一起存储来复制.

请参阅下面Install-Package Microsoft.AspNet.Identity.Samples -Pre'创建空ASP.NET Web应用程序(MVC)项目后随附的标准代码:

var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
Run Code Online (Sandbox Code Playgroud)

我的功能现在如下:

var user = new ApplicationUser { TitleId = model.TitleId, SexId = model.SexId, Forename = model.Forename, Surname = model.Surname, UserName = model.UserName, Email = model.Email, JoinDate = System.DateTime.Now };
Run Code Online (Sandbox Code Playgroud)

如您所见,UserName现在从表单接收值.这一切都很好,除了现在我注册和激活后无法登录.唯一的工作是通过将电子邮件字段中的值放入UserName字段来修改记录,这似乎是愚蠢的.

有人可以告诉我可能错过了什么吗?

Mar*_*zek 9

你必须修改SignInHelper.PasswordSignIn方法.默认情况下,它用于FindByNameAsync检查具有给定名称的用户是否存在:

public async Task<SignInStatus> PasswordSignIn(string userName, string password, bool isPersistent, bool shouldLockout)
{
    var user = await UserManager.FindByNameAsync(userName);
    // (...)
Run Code Online (Sandbox Code Playgroud)

改变它使用FindByEmailAsync:

    var user = await UserManager.FindByEmailAsync(userName);
Run Code Online (Sandbox Code Playgroud)

您可以SignInHelper在*AppCode\IdentityConfig.cs`文件中找到类.


Hai*_*yen 8

在类AccountController.cs 中,方法:public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)。修改了这个:

var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
Run Code Online (Sandbox Code Playgroud)

对此:

try
{
    var user = db.Users.Where(u => u.Email.Equals(model.Email)).Single(); // where db is ApplicationDbContext instance
    var result = await SignInManager.PasswordSignInAsync(user.UserName, model.Password, model.RememberMe, shouldLockout: false);
}
catch (InvalidOperationException)
{
    // the user is not exist
}
Run Code Online (Sandbox Code Playgroud)

原因是UserNameUserEmail具有不同的值,但方法PasswordSignInAsync仅用于UserName检查登录。


小智 8

我遇到了同样的问题,但发现解决方案是将 Marcin 接受的答案和 Hai 的答案结合起来。在AccountController.cs您需要使用FindByEmailAsync(), 而不是FindByNameAsync(),然后使用SignInManager.PasswordSignInAsync()但使用 的值user.UserName作为第一个参数(只要user不为空),而不是model.Email。所以一个完整的答案,基于当前的样板代码,应该是这样的:

    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        // (...) ModelState.IsValid, etc

        string user_name = ""; // in case 'user' is null (user not found)
        var user = await UserManager.FindByEmailAsync(model.Email);

        if (user != null)
        {
            user_name = user.UserName;

            if (!await UserManager.IsEmailConfirmedAsync(user.Id))
            {
                // (...) Require the user to have a confirmed email before they can log on, etc
            }
        }

        // don't use model.Email below, use the value from user.UserName (if user not null)
        var result = await SignInManager.PasswordSignInAsync(user_name, model.Password, model.RememberMe, shouldLockout: false);
        switch (result)
        {
            // (...)
Run Code Online (Sandbox Code Playgroud)