您如何根据登录状态/角色限制/控制用户可以访问的导航路线?

人气:235 发布:2022-10-16 标签: c# xaml xamarin xamarin.forms xamarin.forms.shell

问题描述

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

For my Xamarin.Forms app, I am looking for a way to check if a user has the right role/authentication status to access a page. I know Angular has route guards that can be reused for different routes to check for an authentication status. Is there something similar in Xamarin.Forms?

推荐答案

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

Here is an example showing how you can control the visibility or navigation to your pages based on the login status of the user.

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

By default Shell will always displays initially the first element defined in AppShell.xaml, in this case it will be Login.xaml page.

在下面的例子中Page3"最初将是可见的,因为默认情况下 (Isvisible=true),而Page2"它仅在可绑定属性 IsLoggedtrue 时可见.

In the below example "Page3" will be visible initially because by default (Isvisible=true), while "Page2" it will only be visible when the bindable property IsLogged is true.

您可以在 IsLogged_PropertyChanged() 事件中处理用户登录/注销时的任何逻辑.

You can handle any logic when user Log in/Log out in the IsLogged_PropertyChanged() event.

如果您想要多个/特定或基于页面的角色,您可以随时创建/定义/设计您的角色,在绑定中使用它们,引发并使用其属性更改事件来执行操作.

If you want several/specific or page based roles you can always create/define/design yours, use them in bindings, raise and use their property changed event to execute actions.

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
}

登录.xaml

<StackLayout>
    <Label
        FontSize="45"
        HorizontalOptions="FillAndExpand"
        Text="Login Page" />
    <Button Clicked="Button_Clicked" Text="Log In" />
</StackLayout>

登录.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;  
}

与标签相同的事情

在这个例子中,Symbols"底部标签对于上部标签B"将不可见;属于底部标签字母"的在用户登录之前,剩余的底部选项卡将最初可见.

Same thing with Tabs

In this example "Symbols" bottom tab won't be visible the same for upper tab "B" that belongs to bottom tab "Letters" until the user log-in, the remaining bottoms tabs will be visible initially.

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 以分别隐藏导航栏并隐藏底部标签栏.

Edit

You may also want to add Shell.NavBarIsVisible="False" and Shell.TabBarIsVisible="false" in the Tabbar case, to the LoginPage to respectively hide the navigation bar and hide the bottom tab bar.

980