Blazor進階: Blazor Server and the Logout Problem
Blazor Server App, 多 TabPage, 多 Tab Page,
參考文章
重點資訊
解決方案
關鍵程式碼
Last updated
Blazor Server App, 多 TabPage, 多 Tab Page,
Last updated
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Server;
using Microsoft.AspNetCore.Http;
/// <summary>
/// 加值預設的 AuthenticationStateProvider。
/// </summary>
internal class CustomAuthenticationStateProvider : RevalidatingServerAuthenticationStateProvider
{
//# inject
readonly IHttpContextAccessor _http;
//※ 不要在前端元件使用 IHttpContextAccesser 因為 HttpContext 的狀態並非即時反應的。
readonly AccountService _accSvc;
// resource
readonly AuthenticationState anonymousUser;
public CustomAuthenticationStateProvider(ILoggerFactory loggerFactory, IHttpContextAccessor http, AccountService accSvc) : base(loggerFactory)
{
_http = http;
_accSvc = accSvc;
anonymousUser = new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
/// <summary>
/// 每隔幾秒查看是否還在登入狀態。
/// 因為 HttpContext 的 Cookie 並非即時反應的。這會導致在多畫面應用情境時,若一畫面登出其他畫面卻仍在登入狀態的不同步冏狀。
/// </summary>
protected override TimeSpan RevalidationInterval => TimeSpan.FromSeconds(7);
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
//※ --- 本例為 Cookie Authentication 仍會用到 HttpContext。
var userIdentity = _http.HttpContext?.User.Identity as ClaimsIdentity;
//# 沒有 AuthCookie,回傳anonymousUser。
if (userIdentity == null || !userIdentity.IsAuthenticated)
return Task.FromResult(anonymousUser);
//# 取授權資料
var authUser = _accSvc.GetAuthDataFromPool(userIdentity.Name!);
...
//## 加值授權資料
...
//## 登入完成
var userAuthState = new AuthenticationState(new ClaimsPrincipal(userIdentity));
return Task.FromResult(userAuthState);
}
/// <summary>
/// 查看是否還在登入狀態。與 RevalidationInterval 搭配。
/// </summary>
protected override Task<bool> ValidateAuthenticationStateAsync(AuthenticationState authState, CancellationToken cancellationToken)
{
string userId = authState.User.Identity?.Name ?? string.Empty;
bool isLogged = _accSvc.IsUserLoggedIn(userId); //--- 查看使用者登入狀態。
return Task.FromResult(isLogged);
/// ※ 確認使用者仍是登入,若不是後續將會強制登出。
}
}