无论用户是否登录,如何获取最新信息? [英] How to get fresh information whether the user is logged in?

查看:98
本文介绍了无论用户是否登录,如何获取最新信息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这种情况下,我只对获取信息(无论用户是否登录)感兴趣.

In this particular case I am only interested in getting info whether the user is logged in or not.

遵循答案

Following the answers How to enable/disable elements depending whether the user is logged in or not? I can fetch this information but there is one odd problem.

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

I use Blazor demo app which displays provided "LoginDisplay.razor" component at top, my own page uses following code:

@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}");
  }
}

使用此应用程序时,我需要执行三个步骤:

I have three steps when using this app:

  1. 我启动了应用程序,但尚未登录,"LoginDisplay"显示登录"提示,我的代码打印不合格-好

  1. I start the app, I am not logged in, "LoginDisplay" shows "log in" prompt and my code prints I am not authenticated -- good

我单击登录",登录,然后重定向回我的页面-"LoginDisplay"现在显示我的名字,但我的代码仍可打印,但我尚未通过身份验证(使用"NavMenu.razor"时会出现此错误的打印输出,但使用"Index.razor"时会很好-请参阅下面的更新)

I click on "log in", I log in, I am redirected back to my page -- "LoginDisplay" now shows my name, yet my code still prints I am not authenticated (this incorrect printout happens when using "NavMenu.razor" but it is fine when when using "Index.razor" -- see update below)

我点击了F5(刷新页面)-"LoginDisplay"显示我的名字,并验证我的验证码-如预期

I hit F5 (reload the page) -- "LoginDisplay" shows my name, and the code prints I am authenticated -- as expected

因此,步骤(2)出现了问题-我应该(因为我是)获得了已登录的信息,因此显然"LoginDisplay"有能力实现这一事实.那么我应该在代码中添加什么逻辑以使其也显示我已登录?

So step (2) is problematic -- I should get the info I am logged in (because I am), and obviously "LoginDisplay" is capable of realizing this fact. So what logic should I add to my code that it too would show I am logged in?

更新 @enet回复后,我意识到步骤(2)的结果取决于您将此代码放置在何处-如果将其放置在"NavMenu.razor"中,登录打印输出状态后,您无权获得授权.当我在"Index.razor"中添加相同的代码时,(主页)打印输出正确指示我已登录.

Update After @enet reply I realized the outcome of the step (2) depends where you put this code -- if it placed in "NavMenu.razor" right after logging in the printout states you are not authorized. When I put the same code in "Index.razor" (home page) the printout correctly states I am logged in.

我可以看到渲染"NavMenu"几乎是即时的,而索引"暂停后呈现.因此,问题更多是无论使用该页面如何获取最新的身份验证信息?".

I can see that rendering "NavMenu" is almost immediate, while "Index" is rendered after some pause. So the problem is more "how to get fresh authentication info regardless the page is used?".

推荐答案

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

The following code describes how you can display your message in the MainLayout component:

<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组件时才执行上述代码.为了刷新已验证消息的显示,我们需要再次执行代码.这可以通过执行以下操作来实现:

Note that the above code is executed only when the MainLayout component is initialized. In order to refresh the display of the authenticated message, we need to executed the code once more. This may be achieved by doing the following:

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

In the Authentication component add to the RemoteAuthenticatorView component instance the event handler attribute OnLogInSucceeded that is called after the user has logged in, like this:

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

添加事件处理程序 RefreshMain

 private void RefreshMain()
    {
        NavigationManager.NavigateTo("mainlayout");
    }

事件处理程序代码只需重定向到MainLayout

The event handler code simply redirect to the MainLayout

为NavigationManager添加@inject指令,如下所示:

Add @inject directive for the NavigationManager, like this:

@inject NavigationManager NavigationManager;

请注意,除了上面的代码,您可以简单地使用AuthorizeView组件,如下所示:

Note that instead of the code above you can simply use the AuthorizeView component like this:

<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的主要缺点是,如果基础身份验证状态数据发生更改,则不会自动通知组件.来源...

不要为渲染而烦恼自己.通常,除非不停地重新渲染代码,否则不会有任何问题.

Don't bother yourself too much about rendering. Ordinarily, there is no issue unless your code re-render endlessly.

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

Anyhow, the following code sample describes how you should really do that:

将身份验证"组件中的代码恢复为默认状态

Reverse the code in the Authentication component to its default state

将您在MainLayout中添加的代码更改为以下内容

Change the code you added in the MainLayout to the following

 @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://docs.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();
        });
    }

  }

这篇关于无论用户是否登录,如何获取最新信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆