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操做流程,以后会具体讲解一些功能点