自定义消息处理程序
如果令牌无法更新,则预计将注销。
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
await SetAuthorizationHeader(request);
var response = await base.SendAsync(request, cancellationToken);
if (IsRefreshRequired(response))
{
var tokenRefreshed = await _authService.TryRefreshTokenAsync();
if (tokenRefreshed)
{
await SetAuthorizationHeader(request);
return await base.SendAsync(request, cancellationToken);
}
await _authService.LogoutAsync();
_navigationManager.NavigateTo(Routes.App.Login);
}
return response;
}
private async Task SetAuthorizationHeader(HttpRequestMessage request)
{
var accessToken = await _localStorage.GetItemAsync<string>(Auth.AccessToken);
if (!string.IsNullOrWhiteSpace(accessToken))
{
request.Headers.Authorization = new AuthenticationHeaderValue(Auth.Scheme, accessToken);
}
}
身份验证服务
public async Task LogoutAsync()
{
await RemoveTokensAsync();
AuthStateProvider.NotifyAuthenticationStateChanged();
}
自定义身份验证状态提供者
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
var accessToken = await _localStorage.GetItemAsync<string>(Auth.AccessToken);
if (string.IsNullOrWhiteSpace(accessToken))
{
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
var claims = TokenParser.ParseClaims(accessToken);
var user = new ClaimsPrincipal(new ClaimsIdentity(claims, Auth.AuthType));
return new AuthenticationState(user);
}
public void NotifyAuthenticationStateChanged()
{
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
}
调用LogoutAsync
方法后,它成功将我重定向到“登录”页面,但未更新标题:
如果我要更新页面,或者不是从处理程序而是从剃刀组件中调用LogoutAsync
,那么所有方法都将起作用:
它也不取决于我使用的http客户端。
答案 0 :(得分:1)
基于评论。谢谢@enet和@HenkHolterman。
根本原因:StateHasChanged()
逻辑不会“向外传播”。注销是由内部组件上的调用引起的,LoginDisplay组件不参与默认更新。
解决方案:用户界面重新呈现。没有唯一的方法。
就我而言,我改变了
_navigationManager.NavigateTo(Routes.App.Login);
至
_navigationManager.NavigateTo(Routes.App.Logout);
结果,注销页面触发在组件级别上更改身份验证状态逻辑,然后将用户重定向到登录页面。
另一种方式-在消息处理程序中定义一个事件处理程序,该事件处理程序应在调用NotifyAuthenticationStateChanged之后从LogoutAsync内部触发。此事件的订阅者应该是MainLayout组件,该组件会重新呈现。