如何根据登录状态/角色限制/控制用户可以访问的导航路线?
Posted
技术标签:
【中文标题】如何根据登录状态/角色限制/控制用户可以访问的导航路线?【英文标题】:How can you restrict/control the navigation routes the user can visit based on login status/role? 【发布时间】:2021-03-19 00:39:04 【问题描述】:对于我的 Xamarin.Forms 应用,我正在寻找一种方法来检查用户是否具有正确的角色/身份验证状态来访问页面。我知道 Angular 有路由守卫,可以重复用于不同的路由来检查身份验证状态。 Xamarin.Forms 中有类似的东西吗?
【问题讨论】:
您可以定义一个属性 IsLogged 并绑定页面属性 IsVisible,该属性要求用户登录到该属性。 Shell 将隐藏任何具有 IsVisible="false" 的页面 @Cfun 太棒了!是否也可以显示页面,但基于此登录属性重定向?例如,我有一个帐户页面,您可以在其中查看您的个人资料。但前提是您已登录。因为我仍想显示图标,但有条件地重定向到登录/帐户页面。 【参考方案1】:这是一个示例,展示了如何根据用户的登录状态控制页面的可见性或导航。
默认情况下,Shell 将始终首先显示在AppShell.xaml
中定义的第一个元素,在这种情况下它将是Login.xaml
页面。
在下面的示例中,“Page3”最初是可见的,因为默认情况下 (Isvisible=true
),而“Page2”仅在可绑定属性 IsLogged
为 true
时才可见。
您可以在IsLogged_PropertyChanged()
事件中处理用户登录/注销时的任何逻辑。
如果您想要多个/特定或基于页面的角色,您可以随时创建/定义/设计您的角色,在绑定中使用它们,引发并使用它们的属性更改事件来执行操作。
使用 FlyoutItem
AppShell.xaml
<Shell Shell.FlyoutBehavior="Disabled"..>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
<Tab>
<ShellContent Title="Login" Route="Login">
<local:Login />
</ShellContent>
<ShellContent Title="Page2" Route="Page2"
ContentTemplate="DataTemplate local:Page2"
IsVisible="Binding IsLogged"/>
<ShellContent Title="Page3" Route="Page3"
ContentTemplate="DataTemplate local:Page3"/>
</Tab>
</FlyoutItem>
AppShell.xaml.cs
public bool IsLogged
get => (bool)GetValue(IsLoggedProperty);
set => SetValue(IsLoggedProperty, value);
public static readonly BindableProperty IsLoggedProperty =
BindableProperty.Create("IsLogged", typeof(bool), typeof(AppShell), false, propertyChanged: IsLogged_PropertyChanged);
private static void IsLogged_PropertyChanged(BindableObject bindable, object oldValue, object newValue)
//handle log in/log out event
if ((bool) newValue)
//user just logged in logic
else
//user just logged out logic
Login.xaml
<StackLayout>
<Label
FontSize="45"
HorizontalOptions="FillAndExpand"
Text="Login Page" />
<Button Clicked="Button_Clicked" Text="Log In" />
</StackLayout>
Login.xaml.cs
private async void Button_Clicked(object sender, System.EventArgs e)
IsVisible = false; //hide login page
//Trigger the binding to show pages previously hidden
(Shell.Current as AppShell).IsLogged = true;
await Shell.Current.GoToAsync("//Page2"); //navigate to main page (next after log)
//Enable the flyout: hamburger button
Shell.Current.FlyoutBehavior = FlyoutBehavior.Flyout;
标签也是如此
在此示例中,“符号”底部选项卡对于属于底部选项卡“字母”的上部选项卡“B”将不可见,直到用户登录,其余底部选项卡最初将可见。
AppShell.xaml
<TabBar>
<ShellContent Title="Login" Route="Login">
<local:Login />
</ShellContent>
<Tab Title="Letters">
<ShellContent
Title="A"
ContentTemplate="DataTemplate local:Page1"
Route="Page1" />
<ShellContent
Title="B"
ContentTemplate="DataTemplate local:Page2"
IsVisible="Binding IsLogged"
Route="Page2" />
<ShellContent
Title="C"
ContentTemplate="DataTemplate local:Page3"
Route="Page3" />
</Tab>
<Tab Title="Digits">
<ShellContent
Title="100"
ContentTemplate="DataTemplate local:Page4"
Route="Page4" />
</Tab>
<Tab Title="Symbols" IsVisible="Binding IsLogged">
<ShellContent
Title="!"
ContentTemplate="DataTemplate local:Page5"
Route="Page5" />
</Tab>
</TabBar>
编辑
您可能还想在Tabbar的情况下添加Shell.NavBarIsVisible="False"
和Shell.TabBarIsVisible="false"
到LoginPage分别隐藏导航栏和隐藏底部标签栏。
【讨论】:
谢谢!我想我可以用这个例子来构建我的用例。 AppShell 从何而来?这是您的主页还是应该出现在 xamarin 应用程序中的东西? @GuidoG 是的,它是 MainPage,也可以随意命名,只要您继承 Shell以上是关于如何根据登录状态/角色限制/控制用户可以访问的导航路线?的主要内容,如果未能解决你的问题,请参考以下文章