Microsoft.AspNet.Identity 2.0 用账号或者邮件作为登陆方式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Microsoft.AspNet.Identity 2.0 用账号或者邮件作为登陆方式相关的知识,希望对你有一定的参考价值。

创建一个默认的MVC4.0的项目工程,默认的登陆方式是邮件登陆,那么有没办法改为用账号登陆?

我们来看下默认的登陆Action

 

 

        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }// 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.Email, 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("", "Invalid login attempt.");
                    return View(model);
            }
        }


其中最重要的一个函数

var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);

反编译后,查看源码中标志的红色代码,FindByNameAsync(userName)

// Microsoft.AspNet.Identity.Owin.SignInManager<TUser, TKey>
// Token: 0x06000069 RID: 105 RVA: 0x00005858 File Offset: 0x00003A58
public virtual async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
{
    SignInStatus result;
    if (this.UserManager == null)
    {
        result = SignInStatus.Failure;
    }
    else
    {
        TUser tUser = await this.UserManager.FindByNameAsync(userName).WithCurrentCulture<TUser>();
        if (tUser == null)
        {
            result = SignInStatus.Failure;
        }
        else if (await this.UserManager.IsLockedOutAsync(tUser.Id).WithCurrentCulture<bool>())
        {
            result = SignInStatus.LockedOut;
        }
        else if (await this.UserManager.CheckPasswordAsync(tUser, password).WithCurrentCulture<bool>())
        {
            await this.UserManager.ResetAccessFailedCountAsync(tUser.Id).WithCurrentCulture<IdentityResult>();
            result = await this.SignInOrTwoFactor(tUser, isPersistent).WithCurrentCulture<SignInStatus>();
        }
        else
        {
            if (shouldLockout)
            {
                await this.UserManager.AccessFailedAsync(tUser.Id).WithCurrentCulture<IdentityResult>();
                if (await this.UserManager.IsLockedOutAsync(tUser.Id).WithCurrentCulture<bool>())
                {
                    result = SignInStatus.LockedOut;
                    return result;
                }
            }
            result = SignInStatus.Failure;
        }
    }
    return result;
}

=。=! 聪明如你,应该想到了,默认的方式只是查询Email

按照我们的需求是 用户输入账号或者邮箱就能登陆了,我的解决方式是

public static class IdentityExtension
    {
        public static async Task<ApplicationUser> FindByNameOrEmailAsync
            (this UserManager<ApplicationUser> userManager, string usernameOrEmail, string password)
        {
            var username = usernameOrEmail;
            if (usernameOrEmail.Contains("@"))
            {
                var userForEmail = await userManager.FindByEmailAsync(usernameOrEmail);
                if (userForEmail != null)
                {
                    username = userForEmail.UserName;
                }
            }
            return  await userManager.FindByNameAsync(username);
        }
    }

在Action中直接使用

[HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }
            var user = await UserManager.FindByNameOrEmailAsync(model.PasspotOrEmail, model.Password);
            // This doesn‘t count login failures towards account lockout
            // To enable password failures to trigger account lockout, change to shouldLockout: true
            SignInStatus result = SignInStatus.Failure;
            if(user!=null)
                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("", "Invalid login attempt.");
                    return View(model);
            }
        }

扩展一下,用手机号登陆也可以的哦!

 

 

以上是关于Microsoft.AspNet.Identity 2.0 用账号或者邮件作为登陆方式的主要内容,如果未能解决你的问题,请参考以下文章

Microsoft.AspNet.Identity 的自定义成员身份 - CreateLocalUser 失败

从Microsoft.AspNet.Identity看微软推荐的一种MVC的分层架构

将 Microsoft.AspNet.Identity 升级到 rc1 后找不到 IdentityStoreManager

如何更改 Microsoft.AspNet.Identity.EntityFramework.IdentityUser 中的 id 类型

Microsoft.AspNet.Identity: UserID用整型数据表示, 而不是GUID

实体类型“Microsoft.AspNet.Identity.EntityFramework.IdentityUserLogin<string>”需要定义一个键