[英]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>
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.