访问Blazor Server中的AuthenticationState以在单个位置更新组件

时间:2020-09-16 01:42:48

标签: blazor blazor-server-side

是否可以在Blazor中使用一种方法在诸如MainLayout.razor这样的位置检查身份验证状态,以便在导航到组件时,如果令牌过期,我可以使状态无效?例如,如果您使用OnAfterRenderAsync,则为时已晚,因为页面已呈现。我不想在每个组件上重复检查。因此,我想知道是否存在诸如生命周期函数之类的功能,每次您导航到一个组件时都可以调用该功能,

var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();

        if (authState.User.Identity != null && authState.User.Identity.IsAuthenticated == false)
        {
            Logout();
        }
        StateHasChanged();

1 个答案:

答案 0 :(得分:0)

我为此使用了范围服务。

Program.cs

 builder.Services.AddScoped<IIdentityBroker, IdentityBroker>();

IdentityBroker.cs

public class IdentityBroker : IIdentityBroker
{
    public IdentityBroker(AuthenticationStateProvider authenticationStateProvider)
    {
        this.authenticationStateProvider = authenticationStateProvider;
        authenticationStateProvider.AuthenticationStateChanged += AuthenticationStateProvider_AuthenticationStateChanged;
    }
    public IdentityInformation IdentityInformation => this.identityInformation;

    public event EventHandler AuthenticationStateChanged;
    private void AuthenticationStateProvider_AuthenticationStateChanged(Task<AuthenticationState> task)
    {
        var authState = task.Result;
        UpdateIdentityInfo(authState);
        AuthenticationStateChanged?.Invoke(this, new EventArgs());
    }

    public async ValueTask<IdentityInformation> GetIdentityInfoAsync()
    {
        if (identityInformation == default)
        {
            var authState = await authenticationStateProvider.GetAuthenticationStateAsync();
            UpdateIdentityInfo(authState);
        }
        return identityInformation;
    }

    private void UpdateIdentityInfo(AuthenticationState authState)
    {
        if (authState.User.Identity.IsAuthenticated)
        {
            var user = authState.User;

            this.identityInformation = new IdentityInformation
            {
                DisplayName = user.Identity.Name,
                Email = (user.FindFirst("email")?.Value ?? ""),
                Oid = (user.FindFirst("oid")?.Value ?? "")
            };
        }
        else
        {
            this.identityInformation = default;
        }
    }

    private readonly AuthenticationStateProvider authenticationStateProvider;
    private IdentityInformation identityInformation = default;

}

MainLayout.razor的底部:

@code {
    [Inject]
    public IIdentityBroker IdentityBroker { get; set; }

    protected override async Task OnInitializedAsync()
    {       
        await IdentityBroker.GetIdentityInfoAsync();
        await base.OnInitializedAsync();
    }
}