简体   繁体   English

Blazor WebAssembly - 页面刷新时未调用 GetAuthenticationStateAsync()

[英]Blazor WebAssembly - GetAuthenticationStateAsync() not called on page refresh

I have custom AuthenticationStateProvider in my Blazor WebAssembly app and it's not calling GetAuthenticationStateAsync method on page refresh so if user is logged in and then they manually refresh page ClaimsPrincipal is AuthenticationState is not populated so user can't be Authorized.我的 Blazor WebAssembly 应用程序中有自定义 AuthenticationStateProvider,它不会在页面刷新时调用 GetAuthenticationStateAsync 方法,因此如果用户已登录,然后他们手动刷新页面 ClaimsPrincipal 未填充 AuthenticationState,因此无法授权用户。 I'm using JWT which is saved in cookie for auth, and that cookie remains after page refresh, app just doesn't call GetAuthenticationStateAsync (which it should on page refresh if I learned blazor correctly).我正在使用保存在 cookie 中的 JWT 进行身份验证,并且该 cookie 在页面刷新后仍然存在,应用程序只是不调用 GetAuthenticationStateAsync(如果我正确了解 blazor,它应该在页面刷新时调用)。

Here's my custom AuthenticationStateProvider:这是我的自定义 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);
    }
}

EDIT: It was calling GetAuthenticationStateAsync method the entire time, it was just confusing because I was in debugger and it never hit my breakpoint inside of that method, which is problem I saw other people (still not sure why is that).编辑:它一直在调用 GetAuthenticationStateAsync 方法,这只是令人困惑,因为我在调试器中并且它从未在该方法内部遇到我的断点,这是我看到其他人的问题(仍然不确定为什么会这样)。

It depends on where you call GetAuthenticationStateAsync .这取决于您在哪里调用GetAuthenticationStateAsync
ie in BlazorHero project this call is present in the MainLayout.razor :即在BlazorHero项目中,此调用出现在MainLayout.razor中:

</NotAuthorized>
    <Authorized>
        @(LoadDataAsync())
        <MudLayout RightToLeft="@_rightToLeft">

in MainLayout.razor.cs :MainLayout.razor.cs中:

private async Task LoadDataAsync()
    {
        var state = await _stateProvider.GetAuthenticationStateAsync();
        var user = state.User;
        if (user == null) return;

so I think you need to check where it is called.所以我认为你需要检查它的调用位置。

The MainLayout is rendered every time you load a page.每次加载页面时都会呈现MainLayout

A better solution (cleaner) is to add this code in the AfterRender like:更好的解决方案(更清洁)是在AfterRender中添加此代码,例如:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        await LoadDataAsync();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM