您如何restrict/control 用户可以根据登录status/role 访问的导航路线?

How can you restrict/control the navigation routes the user can visit based on login status/role?

对于我的 Xamarin.Forms 应用程序,我正在寻找一种方法来检查用户是否具有访问页面的正确 role/authentication 状态。我知道 Angular 有路由守卫,可以重复用于不同的路由以检查身份验证状态。 Xamarin.Forms中有类似的东西吗?

下面的示例显示了如何根据用户的登录状态控制页面的可见性或导航。

默认情况下 Shell 将始终最初显示 AppShell.xaml 中定义的第一个元素,在这种情况下它将是 Login.xaml 页。

在下面的示例中,“Page3”最初是可见的,因为默认情况下 (Isvisible=true),而“Page2”仅在可绑定 属性 IsLogged 时可见true.

  • 当用户在 IsLogged_PropertyChanged() 事件中登录 in/Log 时,您可以处理任何逻辑。

  • 如果你想要 several/specific 或基于页面的角色,你总是可以 create/define/design 你的角色,在绑定中使用它们,引发并使用它们的 属性 changed 事件来执行动作。


带有 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分别隐藏导航栏和隐藏底部标签栏。