如何获取用户是否登录的新信息?



在这种特殊情况下,我只对获取用户是否登录的信息感兴趣。

如何根据用户是否登录来启用/禁用元素?我可以获取这些信息,但是有一个奇怪的问题。

我使用Blazor演示应用程序,它显示提供的"LoginDisplay.razor"组件在顶部,我自己的页面使用以下代码:

@code {
protected override async Task OnInitializedAsync()
{
Console.WriteLine("Init");
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var authenticated = authState.User.Identity?.IsAuthenticated ?? false;
Console.WriteLine($"We are {authenticated}");
}
}

我使用这个应用程序有三个步骤:

  1. 我启动应用程序,我没有登录,"LoginDisplay"显示"登录";提示和我的代码打印I am not authenticated - good

  2. 我点击"登录",我登录了,我被重定向回我的页面——"logindisplay"现在显示了我的名字,但我的代码仍然打印我没有经过身份验证(当使用"NavMenu.razor"时,会出现这种错误的打印输出)。但当使用"index .razor"时,它是可以的。——见下文更新)

  3. 我按下F5(重新加载页面)——"LoginDisplay"显示我的名字,代码打印I am authenticated——如预期的那样

所以步骤(2)是有问题的——我应该得到我登录的信息(因为我是),显然"LoginDisplay"能够意识到这个事实。那么,我应该在代码中添加什么逻辑,使它也显示我已登录?

@enet回复后,我意识到步骤(2)的结果取决于您将此代码放在哪里-如果它放在"NavMenu.razor"在登录打印输出状态后,您没有被授权。当我将相同的代码放入& index。razor"(首页)打印结果正确显示我已登录。

我可以看到渲染"NavMenu"几乎是即时的,而"索引"则几乎是即时的。在一段暂停后渲染。因此,问题更多的是"无论使用的是哪个页面,如何获取新的身份验证信息"。

下面的代码描述了如何在MainLayout组件中显示消息:

<LoginDisplay />
<div>IsAuthenticated: @authenticated.ToString()</div>

@code {
bool authenticated;
[CascadingParameter]
private Task<AuthenticationState> authenticationStateTask {get; set;}
protected override async Task OnInitializedAsync()
{
Console.WriteLine("Init");
var authState = await authenticationStateTask;
var user = authState.User;

authenticated = user.Identity?.IsAuthenticated ?? false;
Console.WriteLine($"We are {authenticated}");
}

}

注意,上面的代码只在MainLayout组件初始化时执行。为了刷新已验证消息的显示,我们需要再执行一次代码。这可以通过执行以下操作来实现:

在Authentication组件中,向RemoteAuthenticatorView组件实例添加在用户登录后调用的事件处理程序属性OnLogInSucceeded,如下所示:

<RemoteAuthenticatorView Action="@Action" OnLogInSucceeded="RefreshMain" />

添加事件处理程序RefreshMain

private void RefreshMain()
{
NavigationManager.NavigateTo("mainlayout");
}
事件处理程序代码只是重定向到MainLayout

为NavigationManager添加@inject指令,像这样:

@inject NavigationManager NavigationManager;

请注意,您可以像这样简单地使用AuthorizeView组件来代替上面的代码:

<LoginDisplay />
<div>
<AuthorizeView>
<Authorized>
<div>@context.User.Identity.IsAuthenticated</div>
</Authorized>
<NotAuthorized>
<div>@context.User.Identity.IsAuthenticated</div>
</NotAuthorized>
</AuthorizeView>
</div>

更新

你通常不直接使用AuthenticationStateProvider。使用本文后面介绍的AuthorizeView组件或Task方法。直接使用AuthenticationStateProvider的主要缺点是,如果底层身份验证状态数据发生变化,不会自动通知组件。源…

不要太在意渲染。通常,除非您的代码不断地重新渲染,否则不会出现问题。

无论如何,下面的代码示例描述了您应该如何真正做到这一点:

将Authentication组件中的代码反转为其默认状态

将MainLayout中添加的代码更改为以下

@inherits LayoutComponentBase
@inject AuthenticationStateProvider AuthenticationStateProvider
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="top-row px-4 auth">
<LoginDisplay />
<div>IsAuthenticated: @authenticated.ToString()</div>
<a href="https://learn.microsoft.com/aspnet/" 
target="_blank">About</a>
</div>
<div class="content px-4">
@Body
</div>
</div>
</div>
@code {
private bool authenticated;
protected override void OnInitialized()
{
Task<AuthenticationState> _currentAuthenticationStateTask;
AuthenticationStateProvider.AuthenticationStateChanged += 
OnAuthenticationStateChanged;
_currentAuthenticationStateTask = 
AuthenticationStateProvider.GetAuthenticationStateAsync();
OnAuthenticationStateChanged(_currentAuthenticationStateTask);
}
private void OnAuthenticationStateChanged
(Task<AuthenticationState> authenticationStateTask)
{
_ = InvokeAsync(async () =>
{
var authState = await authenticationStateTask;
var user = authState.User;

authenticated = user.Identity?.IsAuthenticated ?? false;
StateHasChanged();
});
}
}

相关内容

  • 没有找到相关文章