- 从 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>();