我們開新專案時,專案範本可以選擇「個別使用者帳戶」驗證方式,這時候專案就會有登入的機制了,但是很多工程師都不這麼用,理由是:
1. 他是 core first 的方式,不是它們習慣的 db first。
2. 要客製化時要改很多code,感覺太麻煩。
不過有個時機可能會用到他,就是要整合第三方登入機制,如Facebook, Twitter..等等,因為只要設定一下,就可以了。
不過本文最主要的是要說明客製化的實作,也就是專案範本不選 「個別使用者帳戶」 驗證方式 ,實作說明如下
Step 1. 在 Startup.cs 的 ConfigureServices 宣告
public void ConfigureServices(IServiceCollection services)
{
//宣告增加驗證方式,使用 cookie 驗證
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(option =>{
//瀏覽器會限制cookie 只能經由HTTP(S) 協定來存取
option.Cookie.HttpOnly = true;
//登入頁,未鄧入時會自動導到登入頁
option.LoginPath = new PathString("/Account/Login");
//登出網頁(可以省略)
option.LogoutPath = new PathString("/Account/Logout");
//登入有效時間
option.ExpireTimeSpan = TimeSpan.FromMinutes(60);
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//啟用 cookie 原則功能
app.UseCookiePolicy();
//啟用身分識別
app.UseAuthentication();
//啟用授權功能
app.UseAuthorization();
// 這三個前後次序不能對調喔
}
Step 2. 在 Controller 登入實作範例
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Login(LoginVM model)
{
if (ModelState.IsValid)
{
var Pwd = CryptoHelper.HashPassword(model.Password);
var user= _context.User.FirstOrDefault(x=>x.Account== model.Account && x.Password==Pwd);
if (user== null)
{
ViewBag.errMsg = "帳號或密碼輸入錯誤";
return View(model);
}
//取得登入角色
var RoleName =_context.Role.FirstOrDefault(x=>x.Id==user.RoleId).RoleName;
//建立 Claim,也就是要寫到 Cookie 的內容
var claims = new[] { new Claim("UserId", user.Id.ToString()), new Claim("Account", user.Account), new Claim("Name", user.Name), new Claim(ClaimTypes.Role, RoleName) };
//建立證件,類似你的駕照或護照
ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
//將 ClaimsIdentity 設定給 ClaimsPrincipal (持有者)
ClaimsPrincipal principal = new ClaimsPrincipal(claimsIdentity);
//登入動作
await HttpContext.SignInAsync(principal,new AuthenticationProperties()
{
//是否可以被刷新
AllowRefresh = false,
// 設置了一個 1 天 有效期的持久化 cookie
IsPersistent = true,
ExpiresUtc = DateTimeOffset.UtcNow.AddDays(1)
});
return View(model);
}