Owin+ASP.NET Identity浅析系列(一)用户登录注册
在今天,读书有时是件“麻烦”事。它需要你付出时间,付出精力,还要付出一份心境。--仅以《Owin+ASP.NET Identity浅析系列》来祭奠那逝去的……
使用VS2015创建MVC项目运行之后,发现微软很贴心的生成了一套用户授权验证系统,界面也很漂亮,但是扒拉代码一看,囧……新的membership框架,真是太给力了,连数据库表都给你生成了(EF的功劳),问题是,你这一堆一堆的代码,虽然看着很吊(也
确实很吊),但是看着人头大呢,只好研究研究,研究过程记录一下,希望可以帮到那些看到这堆代码之后也头皮发麻的小伙伴们!!!
第一步:删除这一堆代码
微软折腾了一堆代码,说实话对微软的各种viewmodel验证不感冒,所以我要删除它,重新来过!喜欢使用的童鞋,可以保留
备注:亲,别全部删完,请保留IdentityModels类,修改下命名空间,并将其移入App_Start目录中
第二步:拉出自动生成数据表的sql语句(因为后面使用的是mysql数据库,而且引擎还不是innodb)
create table aspnetusers ( Id char(32) primary key, Email varchar(50) null comment '用户邮箱', EmailConfirmed bit not null comment '是否认证邮箱', PasswordHash varchar(100) null comment '账户密码', SecurityStamp varchar(100) null comment '防伪印章', PhoneNumber varchar(100) null comment '用户手机', PhoneNumberConfirmed bit not null comment '是否认证手机', TwoFactorEnabled bit not null comment '是否启用双重身份验证', LockoutEndDateUtc datetime null comment '锁定结束时间', LockoutEnabled bit not null comment '是否启用锁定', AccessFailedCount int not null comment '登陆失败次数', UserName varchar(50) not null comment '用户名称' ) comment '用户表'; create table aspnetuserclaims ( Id int auto_increment primary key, UserId char(32) not null comment '用户Id', ClaimType varchar(100) null comment 'ClaimType', ClaimValue varchar(100) null comment 'ClaimValue' ) comment 'claims表'; create table aspnetuserlogins ( UserId char(32) not null comment '', ProviderKey varchar(100) not null comment '', LoginProvider varchar(100) not null comment '' ) comment '登陆日志表'; create table aspnetuserroles ( UserId char(32) not null comment '', RoleId char(32) not null comment '' ) comment '用户角色表'; create table aspnetroles ( Id char(32) primary key, Name varchar(50) not null comment '' ) comment '用户角色表';
第三步:修改ID的默认赋值,默认是36为GUID,修改为32位
public class ApplicationUser : IdentityUser { public ApplicationUser() { this.Id = System.Guid.NewGuid().ToString("N"); } public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) { // 请注意,authenticationType 必须与 CookieAuthenticationOptions.AuthenticationType 中定义的相应项匹配 var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); // 在此处添加自定义用户声明 return userIdentity; } }
第四步:用户登录,两套代码(一套是默认的登录方式,一套是自定义登录方式)
默认登录方式代码如下:
[HttpPost] public async Task<ActionResult> Login(string account, string password) { // 1. 利用ASP.NET Identity获取用户对象 var user = await UserManager.FindAsync(account, password); if (user == null) return Json(new { Flag = false, Content = "用户名或密码错误!!!" }); // 2. 利用ASP.NET Identity获取identity 对象 var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); // 3. 将上面拿到的identity对象登录 AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true }, identity); return Json(new { Flag = true, Content = "登录成功!!!" }); }
自定义登录方式代码如下:
[HttpPost] public async Task<ActionResult> Login(string account, string password) { // 1. 利用ASP.NET Identity获取用户对象 var user = await UserManager.FindAsync(account, password); if (user == null) return Json(new { Flag = false, Content = "用户名或密码错误!!!" }); // 验证用户密码和登录密码是否一致,FindEmail等方法使用 // UserManager.PasswordHasher.VerifyHashedPassword(user.PasswordHash, password); // 2. 利用ASP.NET Identity获取identity 对象 var claims = new List<System.Security.Claims.Claim>(); claims.Add(new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.NameIdentifier, user.Id)); claims.Add(new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Name, user.UserName)); claims.Add(new System.Security.Claims.Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity")); claims.Add(new System.Security.Claims.Claim("AspNet.Identity.SecurityStamp", user.SecurityStamp)); // 这里可以自定义角色或其他数据 // claims.Add(new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Role, "user")); //声明身份验证方式 var identity = new System.Security.Claims.ClaimsIdentity("ApplicationCookie"); identity.AddClaims(claims); // 3. 将上面拿到的identity对象登录 AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true }, identity); return Json(new { Flag = true, Content = "登录成功!!!" }); }
第五步:用户注册,两套代码(一套是默认的注册方式,一套是自定义注册方式)
默认注册方式代码如下:
[HttpPost] public async Task<ActionResult> Register(Models.RegisterViewModel model) { var user = new ApplicationUser { UserName = model.UserName, Email = model.Email }; var result = await UserManager.CreateAsync(user, model.Password); if (result.Succeeded) { return Json(new { Flag = true, Content = "注册成功!!!" }, JsonRequestBehavior.AllowGet); } else { return Json(new { Flag = false, Content = "注册失败!!!" }, JsonRequestBehavior.AllowGet); } }
自定义注册方式代码如下:
[HttpPost] public async Task<ActionResult> Register(Models.RegisterViewModel model) { var db = new Data.DataContext(); db.Members.Add(new Data.DomainModels.Member() { Id = Guid.NewGuid().ToString("N"), SecurityStamp = Guid.NewGuid().ToString(), Email = model.Email, PasswordHash = UserManager.PasswordHasher.HashPassword(model.Password), UserName = model.UserName }); var result = await db.SaveChangesAsync(); if (result > 0) { return Json(new { Flag = true, Content = "注册成功!!!" }, JsonRequestBehavior.AllowGet); } else { return Json(new { Flag = false, Content = "注册失败!!!" }, JsonRequestBehavior.AllowGet); } }
好了,到这里我们就已经完成了后台的登录注册功能,把代码抽离之后,再看是不是很简单的样子,跟以前的forms认证代码结构差不多啦,封装封装用起来就更方便了!