一、前言
一般我們自己的系統都會用自己設置的一套身份驗證授權的代碼,這次用net core的identity來完成簡單的注冊、登錄和注銷。
二、數據庫
首先就是創建上下文,我這里簡單的建了Users和UserClaim表,要是沒有UserClaim等下的登錄操作是會報錯的,應該是有身份認證方面的關系。
public class DataBaseContext : DbContext { public DataBaseContext(DbContextOptions<DataBaseContext> options) : base(options) { } public DbSet<User> Users { get; set; } public DbSet<IdentityUserClaim<string>> UserClaim { get; set; } } public class User : IdentityUser { public string companyId { get; set; } public string PassWord { get; set; } }
這里User繼承了IdentityUser,IdentityUser中就用很多的基礎字段,像是UserName等所以我們可以再User類中擴展我們的字段。
add-migration Init和update-database Init再控制台執行,生成表。
三、Startup注冊服務
在ConfigureServices中注冊如下
1、數據庫上下文連接
//添加數據庫連接 services.AddDbContext<DataBaseContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
2、添加標識服務,包括默認的UI、令牌提供和身份驗的cookie,並且添加identity信息存儲的實體框架實現,用於關聯數據庫創建用戶獲取用戶信息等。AddDefaultIdentity一個相當於AddIdentity、AddDefaultUI和AddDefaultTokenProviders三個。如果User不繼承IdentityUser使用AddEntityFrameworkStores會報錯。
services.AddDefaultIdentity<User>().AddEntityFrameworkStores<DataBaseContext>();
3、添加Identity的選項,可以設定密碼的強度、長度、使用字符、密碼輸入錯誤次數等等。
services.Configure<IdentityOptions>(options => { // 密碼設置 options.Password.RequireDigit = false; options.Password.RequireLowercase = false; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.Password.RequiredLength = 1; options.Password.RequiredUniqueChars = 1; // 鎖定設置 options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); options.Lockout.MaxFailedAccessAttempts = 5; options.Lockout.AllowedForNewUsers = true; // 用戶設置 options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+"; options.User.RequireUniqueEmail = false; });
4、配置應用程序的cookie
services.ConfigureApplicationCookie(options => { // Cookie設置 options.Cookie.HttpOnly = true; options.ExpireTimeSpan = TimeSpan.FromMinutes(5); options.LoginPath = "/Login/Index"; options.AccessDeniedPath = "/Home/Index"; options.SlidingExpiration = true; });
在Config中注冊身份認證
app.UseAuthentication();
四、簡單的登錄、注冊和注銷
既然是簡單的例子,那我是真的怎么簡單怎么來,代碼也就沒幾條。
先創建一個Home控制器並加上[Authorize]特性,沒得到驗證的就統統無法訪問。按照上面的Startup.cs已經將UserManager依賴注入了,它是用來管理用戶的比如注冊啥的。
[Authorize] public class HomeController : Controller { private UserManager<User> userManager;public HomeController(UserManager<User> _userManager) { userManager = _userManager; } public async Task<IActionResult> Index() { var res = await userManager.GetUserAsync(HttpContext.User); return View(); } }
然后創建一個Login控制器,我們可以在里面寫登錄、注冊和注銷的方法。Login控制器除了UserManager外還要注入SignManager,它是用來用戶登錄、注銷等操作的。
public class LoginController : Controller { //用於提供持久性存儲的用戶信息 private UserManager<User> userManager; private SignInManager<User> signManager; public LoginController(UserManager<User> _userManager,SignInManager<User> _signManager) { userManager = _userManager; signManager = _signManager; } }
1、注冊
注冊直接用CreateAsync方法,會自動在數據庫創建用戶。SignInAsync方法用於剛注冊的馬上用戶登錄。
public async Task<IActionResult> Register() { var user = new User() { UserName = "xu2", PhoneNumber = "123", companyId = "1" }; var result = await userManager.CreateAsync(user, "123"); await signManager.SignInAsync(user, true); if (result.Succeeded) return Redirect("/Home/Index"); return Redirect("/Login/Index"); }
2、登錄
登錄不能用SignInAsync了,要用PasswordSignInAsync密碼登錄
public async Task<IActionResult> Index() { var s = await signManager.PasswordSignInAsync("xu", "123", true, false); return View(); }
3、注銷
這邊直接return view()是無法注銷的,因為cookie會被重新加載,需要return Redirect("/Home/Index")重定向
public async Task<IActionResult> LogOut() { await signManager.SignOutAsync(); return View(); }
4、獲取當前登錄用戶
var res = await userManager.GetUserAsync(HttpContext.User);