Как вы можете ограничить / контролировать маршруты навигации, которые пользователь может посещать на основе статуса / роли входа в систему?

#c# #xaml #xamarin #xamarin.forms #xamarin.forms.shell

#c# #xaml #xamarin #xamarin.forms #xamarin.forms.shell

Вопрос:

Для моего Xamarin.Приложение Forms, я ищу способ проверить, имеет ли пользователь правильную роль / статус аутентификации для доступа к странице. Я знаю, что в Angular есть средства защиты маршрутов, которые можно повторно использовать для разных маршрутов для проверки статуса аутентификации. Есть ли что-то подобное в Xamarin.Формы?

Комментарии:

1. Вы можете определить свойство IsLogged и свойство привязки страниц isVisible, которое требует, чтобы пользователь регистрировался в этом свойстве. Оболочка скроет любую страницу, которая имеет isVisible=»false»

2. @Cfun ах, здорово! Возможно ли также по-прежнему отображать страницу, но перенаправлять на основе этого свойства входа? У меня есть, например, страница учетной записи, где вы можете просмотреть свой профиль. Но только если вы вошли в систему. Потому что я хочу по-прежнему показывать значок, но перенаправлять условно на страницу входа / учетной записи.

3. конечно, вы можете сделать это в конце, вы можете структурировать свое приложение так, как хотите, в зависимости от структуры вашего приложения, если вы предоставите конкретный случай с некоторыми деталями, я бы привел пример, подчеркивающий это.

Ответ №1:

Вот пример, показывающий, как вы можете управлять видимостью или навигацией по своим страницам на основе статуса входа пользователя.

По умолчанию оболочка всегда изначально отображает первый элемент, определенный в 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>
 

Редактировать

Вы также можете добавить Shell.NavBarIsVisible="False" и Shell.TabBarIsVisible="false" в случае панели вкладок на страницу входа, чтобы соответственно скрыть панель навигации и скрыть нижнюю панель вкладок.

Комментарии:

1. Спасибо! Я думаю, что я могу построить свой usecase с помощью этого примера.

2. Откуда берется AppShell? Это ваша главная страница или это то, что должно присутствовать в приложении xamarin?

3. @GuidoG да, это главная страница, также назовите ее так, как вам нравится, если вы подкласс Shell

4. Если кто-то намеревается динамически изменять состояние вкладок во время выполнения, ожидайте, что отслеживание внешнего вида будет вызвано до обновления собственных представлений, поэтому, когда вы обнаружите разницу между количеством вкладок форм и количеством собственных представлений, очередь обновления внешнего вида через 50 мсек.