简体   繁体   English

当用户在 Blazor 中未授权时,我想显示多个带有路由的页面

[英]I want to show multiple pages with routing when user is not Authorized in Blazor

I have App.razor file looking like this:我有 App.razor 文件,如下所示:

@using MyFirstServerSideBlazor.Pages

<CascadingAuthenticationState>
   <Router AppAssembly="@typeof(App).Assembly">
      <Found Context="routeData">
         <AuthorizeView>
            <Authorized>
               <RouteView DefaultLayout="@typeof(MainHeaderLayout)" RouteData="@routeData" />
            </Authorized>
            <NotAuthorized>               
               <RouteView DefaultLayout="@typeof(LoginBody)" RouteData="@routeData" />
            </NotAuthorized>
         </AuthorizeView>        
      </Found>
      <NotFound>
         <PageTitle>Not found</PageTitle>
         <p role="alert">Sorry, there's nothing at this address.</p>
      </NotFound>
   </Router>
</CascadingAuthenticationState>

Is there some way I can specify what routes I want to show, for Unauthenticated user?有什么方法可以为未经身份验证的用户指定要显示的路线吗?

Lets say I want to let Unauthenticated users to navigate to /Login & /SignUp pages.假设我想让未经身份验证的用户导航到 /Login 和 /SignUp 页面。 I could probable use attributes or something on pages to specify that only authenticated user can view them, but this seems to be inconvenient.我可能会在页面上使用属性或其他内容来指定只有经过身份验证的用户才能查看它们,但这似乎不方便。 I'm wondering is there some better solution?我想知道有没有更好的解决方案?

I could also make component that shows different pages, but Im unable to change URI routes that way, example would be:我也可以制作显示不同页面的组件,但我无法以这种方式更改 URI 路由,例如:

<NotAuthorized>               
   <ComponentForUnauthorizedUsers/>
</NotAuthorized>

And then in that component have some logic like this:然后在那个组件中有一些这样的逻辑:

@using MyFirstServerSideBlazor.Componenets.Forms

@inject NavigationManager navigation

@{
   if (ShowLogin)
   {
      <PageTitle>Login</PageTitle>
   }
   else
   {
      <PageTitle>Sign Up</PageTitle>
   } 
}

@{
   if (ShowLogin)
   {
      <LoginForm ChangePageCallback="ChangeToSignUp"/>
   }
   else
   {
      <SignUpComponent ChangePageCallback="ChangeToLogin"/>
   }
}

@code{
   public bool ShowLogin { get; set; } = true;

   public void ChangeToSignUp()
   {
      ShowLogin = false;
      StateHasChanged();
   }    

   public void ChangeToLogin()
   {
      ShowLogin = true;
      StateHasChanged();
   }    
}

this also seems wrong, and this way I cannot use Routing.这似乎也是错误的,这样我就不能使用路由。

There's a handful of options here and I wish I knew the best one myself.这里有一些选择,我希望我自己知道最好的一个。 Here's what I'm currently doing in my app:这是我目前在我的应用程序中所做的:

App.Razor App.Razor

@inject NavigationManager nav

<CascadingAuthenticationState>
    <AuthorizeView>
        <NotAuthorized>
            @{
                /* THE IMPORTANT PART TO REDIRECT AWAY FROM UNAUTHORIZED PAGES */
                if (new Uri(nav.Uri).AbsolutePath.StartsWith("/login") == false)
                    nav.NavigateTo($"/login/{System.Web.HttpUtility.UrlEncode(new Uri(nav.Uri).PathAndQuery)}");
            }
        </NotAuthorized>
    </AuthorizeView>
    <Router AppAssembly="@typeof(Program).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                <Authorizing>
                    <RequestCardTemplate Title="Loading...">
                        <Body>
                            Loading...
                        </Body>
                    </RequestCardTemplate>
                </Authorizing>
            </AuthorizeRouteView>
        </Found>
        <NotFound>
            <LayoutView Layout="@typeof(MainLayout)">
                <h1 class="text-center">Sorry, there's nothing at this address.</h1>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

Deciding which pages require auth确定哪些页面需要身份验证

If a page does not require authorization, then I just write the page as normal.如果页面不需要授权,那么我就照常写页面。 If it does require authorization, then I drop the Authorize attribute into the MyPage.razor file.如果确实需要授权,那么我将 Authorize 属性放入MyPage.razor文件中。

@page "/mypage"
@attribute [Authorize]

@* Rest of page stuff *@

Different components不同的组件

As you mentioned, you can show different links or something if you want to based on whether a user is logged in (authorized?) or not.正如您所提到的,您可以根据用户是否登录(授权?)来显示不同的链接或其他内容。

@* page stuff... *@

<AuthorizeView>
    <Authorized>
        <a href="/myaccount">My Account</a>
        <a href="/myposts">My Posts</a>
    </Authorized>
    <NotAuthorized>
        <a href="/login">Login</a>
        <a href="/signup">Signup</a>
    </NotAuthorized>
</AuthorizeView

@* more page stuff...

Okay with few tweaks I managed to make it Work, In my App.Razor:好的,在我的 App.Razor 中,通过一些调整,我设法让它工作:

<CascadingAuthenticationState>
  <Router AppAssembly="@typeof(App).Assembly">
    <Found Context="routeData">
      <AuthorizeView>
        <Authorized>
          <RouteView DefaultLayout="@typeof(MainHeaderLayout)" RouteData="@routeData" />
        </Authorized>
        <NotAuthorized>
          <UnauthorizedLayout/>
        </NotAuthorized>
      </AuthorizeView>        
    </Found>
    <NotFound>
      <PageTitle>Not found</PageTitle>
      <p role="alert">Sorry, there's nothing at this address.</p>
    </NotFound>
  </Router>
</CascadingAuthenticationState>

Then in UnauthorizedLayout I have this:然后在 UnauthorizedLayout 我有这个:

@inherits LayoutComponentBase

<div class="MainBody">
  <UnauthorizedViewControler/>
</div>

In UnauthorizedViewControler component I have this logic:在 UnauthorizedViewControler 组件中,我有这个逻辑:

@inject NavigationManager navigation

@{
  if (ShowLogin)
  {
    <LoginPage/>
  }
  else
  {
    <SignUpPage/>
  }
}

@code{
  public bool ShowLogin { get; set; } = true;

  protected override void OnInitialized()
  {
    LocationChanged(null,null);
    navigation.LocationChanged += LocationChanged;
    base.OnInitialized();
  }

  void LocationChanged(object sender, LocationChangedEventArgs e)
  {       
    if (navigation.Uri.Contains("/signup"))
    {
      ShowLogin = false;
    }
    else
    {
      ShowLogin = true;
    }

    StateHasChanged();
  }   
}

And for pages themselves:对于页面本身:

// injects & usings...

@layout UnauthorizedLayout
@page "/Login" 

// HTML & Code...

, ,

// injects & usings...

@layout UnauthorizedLayout
@page "/SignUp" 

// HTML & Code...

And this works, I have routing for /Login and /SignUp.这很有效,我有 /Login 和 /SignUp 的路由。

Code, could use some cleaning up, but in principle this works.代码,可以使用一些清理,但原则上这是可行的。

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

相关问题 Blazor WebAssembly 401 未经授权,即使我被授权 - Blazor WebAssembly 401 Unauthorized even when I am authorized Blazor 动态页面的组件路由 - Blazor component routing for dynamic pages 多个项目中的 Blazor 页面 - Blazor pages in multiple projects 我想在用户更改页面时从flipview中删除项目。 有什么我能做的吗? - I want to remove an item from flipview when the user change pages. Is there anything I can do? Blazor - 多参数路由(带逗号)导致异常 - Blazor - Multiple parameters routing (with comma) results in exception 在区域内时的 Blazor 路由和布局 - Blazor routing and layout when inside an area 使用 C# 和 Blazor .... 我希望能够确定用户选择了什么 - Using C# and Blazor.... I want to be able to determine what the user selected 我希望有一个页面可以从用户那里收集信息,并且我想获取这些信息并在其他页面和类上使用它 - I want to have a page that collects information from the user, and i want to take that information and use it on other pages and classes 未授权用户时出现登录对话框 - Login Dialog Appears When User is Not Authorized 尝试以未授权用户身份提交表单时出现问题 - Problem when trying to submit form as a not authorized user
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM