測試如何在自己的專案加入登入驗證功能
概述
想要簡單測試自訂的方式進行登入驗證, 並且將登入功能製成 Area 的方式測試,順便測試登入過時, 故進行簡單測試
內容
首先, 我們需要加入 "LoginExpireMinute": 5 在 AppSetting 內, 並且在 Startup 的 Configuration Service 加入讀取 App Setting 的逾時變數
// Get AppSetting Value
double LoginExpireMinute = this.Configuration.GetValue<double>("LoginExpireMinute");
// Registe CookieAuthentication, Scheme
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(
option =>
{
option.LoginPath = new PathString("/Account/Login/Index");
option.LogoutPath = new PathString("/Home/Index");
//Over Time
option.ExpireTimeSpan = TimeSpan.FromMinutes(LoginExpireMinute);
});
除此之外, 我們還需要在 Configure 內加入驗證功能
// add Authentication
app.UseAuthentication();
app.UseAuthorization();
在 Endpoint 內加入 Area 的 Route 路徑
endpoints.MapAreaControllerRoute(
name: "areaAccount",
areaName: "Account",
pattern: "Account/{controller=Home}/{action=Index}/{id?}");
完成 Startup 的設定後, 我們在 _Layout <ul> 結束後加入 <partial name="_LoginPartial"> ,以便後續將 Login 與 Logout 隔開。
加入後, 新增一個 View 在 Shared 內並且命名 _LoginPartial。 這樣做的異動將會在上方列表的右方。 我們將新增後加入以下程式碼:
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Account" asp-controller="Login" asp-action="Logout">LogOut</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" id="login" asp-area="Account" asp-controller="Login" asp-action="Index">Login</a>
</li>
</ul>
完成後, 在專案下新增一個文件夾叫 Area 與在該文件夾右鍵新增 Area, 選擇 MVC 的架構並且命名為 Account。
完成即會長出與 MVC 相同的專案架構在 Account 文件夾內。
開啟 Account 內的 Views 並且新增一個 Login 文件夾已做頁面區分, 並且在內新增一個 Index 頁面以供登入功能做作用。
@model CustomLogin.Areas.Account.Models.LoginModel
@{
ViewData["Title"] = "Login";
}
<h1>Login Account</h1>
<div class="col-md-10 offset-1">
<form asp-action="Index" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<div class="input-group">
<input asp-for="LoginAccount" class="form-control" />
</div>
<span asp-validation-for="LoginPassword" class="text-danger"></span>
</div>
<div class="form-group">
<div class="input-group">
<input asp-for="LoginPassword" class="form-control" />
</div>
<span asp-validation-for="LoginPassword" class="text-danger"></span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">Log In</button>
</div>
<div style="color:red;">
@ViewData["errMsg"]
</div>
</form>
</div>
@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
完成後, 將 Shared 內的 _ValidationScriptsPartial 與 View 以下的 _ViewStart 與 _ViewImport 複製一份至 Account/Views 下,以便讀取界面設定
Views 設定結束後, 我們開始設定 Models,在 Account / Models 內創建一個 LoginModel 的類別,並加入:
public class LoginModel
{
public String LoginAccount { get; set; }
public String LoginPassword { get; set; }
}
完成後, 在 Controller 創建一個 LoginController 並在內進行設計驗證功能。
[Area("Account")]
[AutoValidateAntiforgeryToken]
public class LoginController : Controller
{
// get appsetting
private readonly IConfiguration config;
public LoginController(IConfiguration config)
{
this.config = config;
}
public IActionResult Index()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Index(LoginModel login)
{
// check model
if (ModelState.IsValid)
{
// check account
if (((login.LoginAccount == "test") && (login.LoginPassword == "test")) == false)
{
ViewBag.errMsg = "Login Fail";
return View();
}
else
{
// get login account
Claim[] claims = new[] { new Claim("Account", login.LoginAccount) };
// scheme
ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
// Login
ClaimsPrincipal principal = new ClaimsPrincipal(claimsIdentity);
// get over setting value
double loginExpireMinute = this.config.GetValue<double>("LoginExpireMinute");
// IsPersistent = false,web will close and logout
// if web over setting will logout
/* ExpiresUtc = DateTime.Now.AddMinutes(loginExpireMinute) */
await HttpContext.SignInAsync(principal, new AuthenticationProperties() { IsPersistent = false, });
return Redirect("/Home/Index");
}
}
else
{
ViewData["errMsg"] = "Please Input";
return View();
}
}
public async Task<IActionResult> Logout()
{
//logout
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return Redirect("/Home/Privacy");
}
以上完成後即可進行測試,即時完成相關自訂帳號驗證功能。中間可能有其他可以強化的地方,但是主要是測試功能, 將不多加以設計。
參考文件
[ASP.net Core 3.0] 實作 Cookie based 登入機制(CookieAuthentication) 取代ASP.Net Framework的表單驗證(FormsAuthentication)登入 - https://dotblogs.com.tw/shadow/2019/01/16/105615
完整專案 - https://github.com/RyukHau/CustomLogin
感謝閱讀