1. 自定義屬性
參考:ASP.NET Identity 2.0: Customizing Users and Roles
以擴展ApplicationUser為例。
1.1. 新增Password屬性
修改IdentityModel.cs,ApplicationUser繼承自IdentityUser,只需為它增加Password屬性,用來保存密碼明文。
public class ApplicationUser : IdentityUser { public ApplicationUser() : base() { } public ApplicationUser(string userName) : base(userName) { }
/// <summary> ///密碼明文 /// </summary> [Required] [Display(Name = "密碼")] public string Password { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUserManager manager) { // 請注意,authenticationType 必須與 CookieAuthenticationOptions.AuthenticationType 中定義的相應項匹配 var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); // 在此處添加自定義用戶聲明 return userIdentity; } } |
1.2. 修改ViewModel
修改AccountViewModel.cs,采用用戶名登錄,為登錄與注冊ViewModel增加用戶名。
public class LoginViewModel { [Required] [Display(Name = "用戶名")] public string Username { get; set; }
[Required] [DataType(DataType.Password)] [Display(Name = "密碼")] public string Password { get; set; }
[Display(Name = "記住我?")] public bool RememberMe { get; set; } } |
public class RegisterViewModel { [Required] [Display(Name = "用戶名")] public string Username { get; set; }
[Required] [EmailAddress] [Display(Name = "電子郵件")] public string Email { get; set; }
[Required] [StringLength(100, ErrorMessage = "{0} 必須至少包含 {2} 個字符。", MinimumLength = 6)] [DataType(DataType.Password)] [Display(Name = "密碼")] public string Password { get; set; }
[DataType(DataType.Password)] [Display(Name = "確認密碼")] [Compare("Password", ErrorMessage = "密碼和確認密碼不匹配。")] public string ConfirmPassword { get; set; } } |
1.3. 修改Controller
修改AccountController.cs的Login與Register方法。
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (!ModelState.IsValid) { return View(model); }
// 這不會計入到為執行帳戶鎖定而統計的登錄失敗次數中 // 若要在多次輸入錯誤密碼的情況下觸發帳戶鎖定,請更改為 shouldLockout: true var result = await SignInManager.PasswordSignInAsync(model.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("", "無效的登錄嘗試。"); return View(model); } } |
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new ApplicationUser { UserName = model.Username, Password = model.Password, Email = model.Email }; var result = await UserManager.CreateAsync(user, model.Password); if (result.Succeeded) { await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
// 有關如何啟用帳戶確認和密碼重置的詳細信息,請訪問 http://go.microsoft.com/fwlink/?LinkID=320771 // 發送包含此鏈接的電子郵件 // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id); // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme); // await UserManager.SendEmailAsync(user.Id, "確認你的帳戶", "請通過單擊 <a href=\"" + callbackUrl + "\">這裏</a>來確認你的帳戶");
return RedirectToAction("Index", "Home"); } AddErrors(result); }
// 如果我們進行到這一步時某個地方出錯,則重新顯示表單 return View(model); } |
1.4. 修改View
Login.cshtml
<h4>使用本地帳戶登錄。</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(m => m.Username, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.Username, new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.Username, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <div class="checkbox"> @Html.CheckBoxFor(m => m.RememberMe) @Html.LabelFor(m => m.RememberMe) </div> </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="登錄" class="btn btn-default" /> </div> </div> |
Register.cshtml
<h4>創建新帳戶。</h4> <hr /> @Html.ValidationSummary("", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(m => m.Username, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.Username, new { @class = "form-control" }) </div> </div> <div class="form-group"> @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) </div> </div> <div class="form-group"> @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) </div> </div> <div class="form-group"> @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" class="btn btn-default" value="注冊" /> </div> </div> |
1.5. 運行效果
登錄
注冊