c# - Blazor WebAssembly - 页面刷新时未调用 GetAuthenticationStateAsync()
问题描述
我在我的 Blazor WebAssembly 应用程序中有自定义 AuthenticationStateProvider 并且它没有在页面刷新时调用 GetAuthenticationStateAsync 方法,因此如果用户登录然后他们手动刷新页面 ClaimsPrincipal 是 AuthenticationState 未填充,因此用户无法被授权。我正在使用保存在 cookie 中用于身份验证的 JWT,并且该 cookie 在页面刷新后仍然存在,应用程序只是不调用 GetAuthenticationStateAsync (如果我正确地学习了 blazor,它应该在页面刷新时调用)。
这是我的自定义 AuthenticationStateProvider:
public class CustomAuthenticationStateProvider : AuthenticationStateProvider
{
private readonly HttpClient _httpClient;
public CustomAuthenticationStateProvider(
IHttpClientFactory httpClientFactory)
{
_httpClient = httpClientFactory.CreateClient("APIClient");
}
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
//TODO get token from cookie
var savedToken = "";
if (string.IsNullOrWhiteSpace(savedToken))
{
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(ParseClaimsFromJwt(savedToken), "jwt")));
}
public void MarkUserAsAuthenticated(string email)
{
var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, email) }, "apiauth"));
var authState = Task.FromResult(new AuthenticationState(authenticatedUser));
NotifyAuthenticationStateChanged(authState);
}
public void MarkUserAsLoggedOut()
{
var anonymousUser = new ClaimsPrincipal(new ClaimsIdentity());
var authState = Task.FromResult(new AuthenticationState(anonymousUser));
NotifyAuthenticationStateChanged(authState);
}
}
编辑:它一直在调用 GetAuthenticationStateAsync 方法,这只是令人困惑,因为我在调试器中并且它从未在该方法内达到我的断点,这是我看到其他人的问题(仍然不确定为什么会这样)。
解决方案
这取决于你在哪里打电话GetAuthenticationStateAsync
。
即在BlazorHero项目中,此调用存在于MainLayout.razor中:
</NotAuthorized>
<Authorized>
@(LoadDataAsync())
<MudLayout RightToLeft="@_rightToLeft">
在MainLayout.razor.cs:
private async Task LoadDataAsync()
{
var state = await _stateProvider.GetAuthenticationStateAsync();
var user = state.User;
if (user == null) return;
所以我认为您需要检查它的名称。
每次加载页面时都会呈现MainLayout。
更好的解决方案(更清洁)是添加以下代码AfterRender
:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await LoadDataAsync();
}
}
推荐阅读
- php - 我在 php 中遇到“echo”为空的问题
- node.js - 错误:MongoError:管理员未授权执行命令
- php - 在 codeigniter 中使用 tank auth 时无法重定向到 auth 控制器的登录方法
- sql - 如何在多行中创建我的插入语句?
- python - 如何为 Windows 的 pyculib 添加正确的分发渠道?
- reactjs - 如何从 TextInput 字段导航到新页面?
- javascript - 关于chart.js上的标签动画是否可行
- nosql - 在Bitcask中,旧文件合并压缩后,内存中的索引/哈希表如何更新?
- spring - 避免 Spring Boot App 在启动时连接到 Cassandra
- marklogic - 如何从 NodeJs 应用程序调用 Marklogic REST API 扩展