ASP.NET Core 的 identity 是一種需要用戶登錄的會員系統,用戶可以創建一個登錄信息存儲在 Identity 的的賬號, 或者也可以使用第三方登錄,支持的第三方登錄包括:Facebook, Google, Microsoft Account, and Twitter. Identi ...
ASP.NET Core 的 identity 是一種需要用戶登錄的會員系統,用戶可以創建一個登錄信息存儲在 Identity 的的賬號,
或者也可以使用第三方登錄,支持的第三方登錄包括:Facebook, Google, Microsoft Account, and Twitter.
Identity 使用Sql Server 存儲用戶的姓名,密碼等數據,當然你也可以選擇其他的存儲工具進行存儲
這篇教程,將會講解如何使用Identity進行用戶的註冊,登錄,登出
1.創建一個帶認證(authentication)的web應用
- 文件->新建->項目
- 選擇ASP.NET Core Web 應用程式,命名WebApp1 ,點擊確定
- 然後選擇web 應用程式,然後更改身份驗證
- 選擇個人用戶賬號,確定
生成的項目會提供 ASP.NET Core Identity 功能,並且 Identity area 會暴露 下麵幾個 終端(endpoint):
- /Identity/Account/Login
- /Identity/Account/Logout
- /Identity/Account/Manage
2.遷移
觀察生成的代碼,發現migration已經生成了,只需要更新到資料庫
在nuget 程式控制臺中,輸入:
Update-Database
直接在vs中的視圖,打開sql server 對象管理器,查看資料庫效果,確認資料庫更新成功:
3.配置 Identity 服務(Identity service)
服務被添加到了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); }
4.添加 註冊,登錄,登錄功能
- 在解決方案的項目上,右鍵添加->新搭建基架的項目
- 選擇標識,添加
- 然後選擇你想添加的項
這裡的數據上下文中需要選中一個數據的,註意
之後,會生成相應的一些文件,包括註冊,登錄,登出
5.現在再看下,生成的代碼
註冊
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">[email protected]!</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>
6.驗證Identity
預設的web項目模板允許匿名訪問到主頁的,為了驗證Identity,給Privacy 頁面增加 [Authorize]
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc.RazorPages; namespace WebApp1.Pages {
[Authorize] public class PrivacyModel : PageModel { public void OnGet() { } } }
7.運行
測試註冊,登錄,登出功能
以及認證效果對比(即Privacy頁面增加Authrize前後):
加之前:不需要登錄,即可訪問Privacy頁面
加之後:需要登錄,才能訪問此頁面
這裡先記錄添加Identity操作流程,之後會具體講解一些功能點