- 从 GitHub 下载源码
- 打开 15 start 项目
- 打开程序包管理控制台,更新数据库
自动生成的 Startup 里面的部分代码就启用了 Identity:
public void ConfigureServices(IServiceCollection services){...services.AddDefaultIdentity<IdentityUser>().AddDefaultUI(UIFramework.Bootstrap4).AddEntityFrameworkStores<ApplicationDbContext>();...}public void Configure(IApplicationBuilder app, IHostingEnvironment env){...app.UseCookiePolicy();app.UseAuthentication();...}
UserController
通过依赖注入的 UserManager 实现对 User 的操控。
[Authorize]public class UserController : Controller{private readonly UserManager<ApplicationUser> _userManager;public UserController(UserManager<ApplicationUser> userManager){_userManager = userManager;}public async Task<IActionResult> Index(){var users = await _userManager.Users.ToListAsync();return View(users);}public IActionResult AddUser(){return View();}[HttpPost]public async Task<IActionResult> AddUser(UserCreateViewModel userAddViewModel){if (!ModelState.IsValid){return View(userAddViewModel);}var user = new ApplicationUser{UserName = userAddViewModel.UserName,Email = userAddViewModel.Email,IdCard = userAddViewModel.IdCard,BirthDate = userAddViewModel.BirthDate};var result = await _userManager.CreateAsync(user, userAddViewModel.Password);if (result.Succeeded){return RedirectToAction("Index");}foreach (var error in result.Errors){ModelState.AddModelError(string.Empty, error.Description);}return View(userAddViewModel);}public async Task<IActionResult> EditUser(string id){var user = await _userManager.FindByIdAsync(id);if (user == null){return RedirectToAction("Index");}var userEditViewModel=new UserEditViewModel{UserName = user.UserName,Email = user.Email};return View(userEditViewModel);}[HttpPost]public async Task<IActionResult> EditUser(string id, UserEditViewModel userEditViewModel){var user = await _userManager.FindByIdAsync(id);if (user == null){return RedirectToAction("Index");}user.UserName = userEditViewModel.UserName;user.Email = userEditViewModel.Email;user.IdCard = userEditViewModel.IdCard;user.BirthDate = userEditViewModel.BirthDate;var result = await _userManager.UpdateAsync(user);if (result.Succeeded){return RedirectToAction("Index");}ModelState.AddModelError(string.Empty, "更新用户信息时发生错误");return View(userEditViewModel);}[HttpPost]public async Task<IActionResult> DeleteUser(string id){var user = await _userManager.FindByIdAsync(id);if (user != null){var result = await _userManager.DeleteAsync(user);if (result.Succeeded){return RedirectToAction("Index");}ModelState.AddModelError(string.Empty, "删除用户时发生错误");}else{ModelState.AddModelError(string.Empty, "用户找不到");}return View("Index", await _userManager.Users.ToListAsync());}}
UserXxViewModel
User 的各种视图模型,通过特性标注实现基本的验证和显式设置:
public class UserCreateViewModel{[Required][Display(Name = "用户名")]public string UserName { get; set; }[Required][DataType(DataType.EmailAddress)][RegularExpression(@"(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|""(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*"")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])", ErrorMessage = "Email的格式不正确")]public string Email { get; set; }[Required][DataType(DataType.Password)]public string Password { get; set; }[Required][Display(Name = "身份证号")][StringLength(18, MinimumLength = 18, ErrorMessage = "{0}的长度是{1}")]public string IdCard { get; set; }[Required][Display(Name = "出生日期")][DataType(DataType.Date)]public DateTime BirthDate { get; set; }}
扩展 IdentityUser
查看 IdentityUser 的源码,不难发现它的属性并不多。我们可以通过继承它来创建属性更丰富的 IdentityUser。
添加了身份证号和出生日期的 ApplicationUser:
public class ApplicationUser:IdentityUser{[MaxLength(18)]public string IdCard { get; set; }[DataType(DataType.Date)]public DateTime BirthDate { get; set; }}
然后将 Configure Services 里面的代码:services.AddDefaultIdentity<IdentityUser> 修改为 services.AddDefaultIdentity<ApplicationUser>
然后修改 ApplicationDbContext 指明 IdentityUser 的实现类为 ApplicationUser:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>{...}
然后 Add-Migration + Update-Database 更新数据库。
最后将程序中所有原来使用 IdentityUser 的地方替换为 ApplicationUser。
自定义密码规则
Identity 默认要求用户设置复杂的强密码,我们可以通过 IdentityOptions 自定义密码规则。
services.AddDefaultIdentity<ApplicationUser>(options =>{options.Password.RequireNonAlphanumeric = false;options.Password.RequireLowercase = false;options.Password.RequireUppercase = false;options.Password.RequiredLength = 6;}).AddDefaultUI(UIFramework.Bootstrap4).AddEntityFrameworkStores<ApplicationDbContext>();

