ASP.NET Core 的 identity 是一種須要用戶登陸的會員系統,用戶能夠建立一個登陸信息存儲在 Identity 的的帳號,git
或者也可使用第三方登陸,支持的第三方登陸包括:Facebook, Google, Microsoft Account, and Twitter.web
Identity 使用Sql Server 存儲用戶的姓名,密碼等數據,固然你也能夠選擇其餘的存儲工具進行存儲redis
這篇教程,將會講解如何使用Identity進行用戶的註冊,登陸,登出sql
生成的項目會提供 ASP.NET Core Identity 功能,而且 Identity area 會暴露 下面幾個 終端(endpoint):數據庫
觀察生成的代碼,發現migration已經生成了,只須要更新到數據庫緩存
在nuget 程序控制臺中,輸入:async
Update-Database
直接在vs中的視圖,打開sql server 對象管理器,查看數據庫效果,確認數據庫更新成功:ide
服務被添加到了StartUp下的 ConfigureServices方法中工具
public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer( Configuration.GetConnectionString("DefaultConnection"))); services.AddDefaultIdentity<IdentityUser>() .AddDefaultUI(UIFramework.Bootstrap4) .AddEntityFrameworkStores<ApplicationDbContext>();
//這裏對Identity作一些配置 services.Configure<IdentityOptions>(options => { // Password settings.密碼配置 options.Password.RequireDigit = true; options.Password.RequireLowercase = true; options.Password.RequireNonAlphanumeric = true; options.Password.RequireUppercase = true; options.Password.RequiredLength = 6; options.Password.RequiredUniqueChars = 1; // Lockout settings.鎖定設置 options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); options.Lockout.MaxFailedAccessAttempts = 5; options.Lockout.AllowedForNewUsers = true; // User settings.用戶設置 options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+"; options.User.RequireUniqueEmail = false; }); services.ConfigureApplicationCookie(options => { // Cookie settings 緩存設置 options.Cookie.HttpOnly = true; options.ExpireTimeSpan = TimeSpan.FromMinutes(5); options.LoginPath = "/Identity/Account/Login"; options.AccessDeniedPath = "/Identity/Account/AccessDenied"; options.SlidingExpiration = true; }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }
這裏的數據上下文中須要選中一個數據的,注意post
以後,會生成相應的一些文件,包括註冊,登陸,登出
public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl = returnUrl ?? Url.Content("~/"); if (ModelState.IsValid) { var user = new IdentityUser { UserName = Input.Email, Email = Input.Email }; var result = await _userManager.CreateAsync(user, Input.Password); //建立帳戶
if (result.Succeeded) { _logger.LogInformation("User created a new account with password."); var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); //生成郵箱驗證碼 var callbackUrl = Url.Page( //生成驗證的回調地址 "/Account/ConfirmEmail", pageHandler: null, values: new { userId = user.Id, code = code }, protocol: Request.Scheme); await _emailSender.SendEmailAsync(Input.Email, "Confirm your email", //發送郵箱驗證郵件 $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>."); await _signInManager.SignInAsync(user, isPersistent: false); //登陸 return LocalRedirect(returnUrl); } foreach (var error in result.Errors) { ModelState.AddModelError(string.Empty, error.Description); } } // If we got this far, something failed, redisplay form return Page(); }
建立成功後,會直接顯示登陸狀態
public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl = returnUrl ?? Url.Content("~/"); if (ModelState.IsValid) { // This doesn't count login failures towards account lockout // To enable password failures to trigger account lockout, // set lockoutOnFailure: true var result = await _signInManager.PasswordSignInAsync(Input.Email, //密碼登陸 Input.Password, Input.RememberMe, lockoutOnFailure: true); if (result.Succeeded) //登陸成功 { _logger.LogInformation("User logged in."); return LocalRedirect(returnUrl); } if (result.RequiresTwoFactor) //兩步驗證 { return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe }); } if (result.IsLockedOut) //鎖定 { _logger.LogWarning("User account locked out."); return RedirectToPage("./Lockout"); } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return Page(); } } // If we got this far, something failed, redisplay form return Page(); }
public async Task<IActionResult> OnPost(string returnUrl = null) { await _signInManager.SignOutAsync(); //登出 _logger.LogInformation("User logged out."); if (returnUrl != null) { return LocalRedirect(returnUrl); } else { return Page(); } }
@using Microsoft.AspNetCore.Identity @inject SignInManager<IdentityUser> SignInManager @inject UserManager<IdentityUser> UserManager <ul class="navbar-nav"> @if (SignInManager.IsSignedIn(User)) { <li class="nav-item"> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello@User.Identity.Name!</a> </li> <li class="nav-item"> <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post"> <button type="submit" class="nav-link btn btn-link text-dark">Logout</button> </form> </li> } else { <li class="nav-item"> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a> </li> <li class="nav-item"> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a> </li> } </ul>
默認的web項目模板容許匿名訪問到主頁的,爲了驗證Identity,給Privacy 頁面增長 [Authorize]
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc.RazorPages; namespace WebApp1.Pages {
[Authorize] public class PrivacyModel : PageModel { public void OnGet() { } } }
測試註冊,登陸,登出功能
以及認證效果對比(即Privacy頁面增長Authrize先後):
加以前:不須要登陸,便可訪問Privacy頁面
加以後:須要登陸,才能訪問此頁面
這裏先記錄添加Identity操做流程,以後會具體講解一些功能點