在 Blazor 專案上使用 Cookie 登入
在 Blazor 上做登入功能,我原以為會比傳統的 ASP.NET 專案簡單,但事實上沒有,先說結論,還是要寫 controller。
首先,我把邏輯抽到 service,所以需要透過 DI 取得 IHttpContextAccessor
物件:
private IHttpContextAccessor _httpContextAccessor;
public UserAppService(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
接下來登入的程式碼就好寫了,網路上很多範例:
public async Task<bool> Login(string username, string password)
{
if (UserData.UserName == username && UserData.UserPassword == password)
{
ClaimsIdentity claimsIdentity = new ClaimsIdentity(new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, username)
}, "auth");
ClaimsPrincipal claims = new ClaimsPrincipal(claimsIdentity);
await _httpContextAccessor.HttpContext.SignInAsync(claims);
return true;
}
return false;
}
public async Task Logout()
{
await _httpContextAccessor.HttpContext.SignOutAsync();
}
public bool CheckLoginState()
{
if (_httpContextAccessor.HttpContext.User.Identity.IsAuthenticated)
{
return true;
}
return false;
}
再來是登入的畫面,雖然是 blazor 頁面,但加入的還是傳統的 Form:
@page "/Login"
@using AIPicturesAlbumWebAP.Data;
@inject IUserAppService userAppService
<h3>登入</h3>
<form method="post" action="Auth">
<input type="text" name="UserName" />
<input type="password" name="Password" />
<input type="submit" value="登入" />
</form>
@code {
}
最後是 controller,這部份也是沒什麼特別的,就是拿到參數後由 service 執行登入:
[Route("/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
private IUserAppService _userAppService;
public AuthController(IUserAppService userAppService)
{
_userAppService = userAppService;
}
[HttpPost]
public async Task<IActionResult> Login([FromForm] LoginModel loginModel)
{
var isLogin = await _userAppService.Login(loginModel.UserName, loginModel.Password);
if (isLogin)
{
return Redirect("/UploadPic");
}
return Redirect("/Login");
}
}
最後別漏掉在 Program.cs 上的設定:
builder.Services.AddAuthentication("Cookies").AddCookie();
builder.Services.AddHttpContextAccessor();
有興趣的可以到 GitHub 頁面看原始碼:
參考資料