Маршруты Охранники, вызывающие неправильное поведение навигации по маршруту

У меня проблема с навигацией по различным маршрутам.

У меня есть два разных модуля маршрута.

app.routes.ts:

Содержит только LoginPage:

export const routes: Routes = [
  {
    path: 'login',
    component: LoginPageComponent,
    canActivate: [PreventLoggedInAccess]
  },
  {
    path: '',
    redirectTo: 'login',
    pathMatch: 'full'
  },
  {
    path: '**',
    redirectTo: 'login'
  }
];

export const Routing: ModuleWithProviders = 
    RouterModule.forRoot(routes, { useHash : true });

С PreventLoggedInAccess.canActivate, если пользователь уже зарегистрирован, он перенаправляет его в раздел с /app prefix и дочерним маршрутом home. Он определяется как:

canActivate(): boolean {
  if (!this._authService.isAuthenticated()) {
      return true;
  }
  this._router.navigate(['/app/home']);
  return false;
}

pages.routes.ts:

Содержит все подпрограммы /app, доступные только в том случае, если пользователь вошел в систему. Это достигается с помощью AuthGuardService.canActivateChild:

export const pageRoutes: Routes = [
  {
    path: 'app',
    component: PagesComponent,
    canActivateChild: [AuthGuardService],
    children: [
      { path: '', redirectTo: 'home', pathMatch: 'full' },
      { path: 'home', component: HomePageComponent },
      { path: 'contents', component: ContentsComponent },
    ]
  }
];

export const Routing: ModuleWithProviders = RouterModule.forChild(pageRoutes);

С последним, который перенаправляет /login если пользователь не вошел в систему. Он определяется как:

canActivateChild(): boolean {
  if (this._authService.isAuthenticated()) {
      return true;
  }
  this._router.navigate(['login']);
  return false;
}

Когда я перемещаюсь из app/home в app/contents он переходит только к ContentsComponent после двух раз. Итак, если я делаю два раза this._router.navigate(['app/components']); он работает, если я делаю это только один раз, маршрут изменяется с app/home на app/route на 1 мс, и он возвращается в app/home, а если я делаю это во второй раз, он меняет маршрут. Хотя, если я в app/contents и пытаюсь перейти к app/home он меняет маршрут просто отлично.

isAuthenticated работает отлично. Оба authguards работают очень хорошо, поэтому, если я пытаюсь получить доступ к любому дочернему маршруту app когда я не зарегистрирован, я получаю перенаправление для входа в систему и если я пытаюсь получить доступ к login при login систему, я получаю перенаправление в app/home.

Мне удалось немного отладить, и я заметил следующий поток:

  • Первая попытка - app/homeapp/contents:
    • navigate(['app/contents']) вызывается
    • PreventLoggedInAccess.canActivate
    • AuthGuardService.canActivateChild
  • Вторая попытка - app/homeapp/contents:
    • navigate(['app/contents']) вызывается
    • AuthGuardService.canActivateChild

Конечно, ожидаемое поведение - второе.

РЕДАКТИРОВАТЬ

Удаление this._router.navigate([/app/home]); из PreventLoggedInAccess.canActivate решает проблему

canActivate(): boolean {
  if (!this._authService.isAuthenticated()) {
      return true;
  }
  return false;
}

Но все же я не понимаю, почему PreventLoggedInAccess.canActivate вызывается при навигации по дочернему app хотя к AuthGuardService.canActivateChild прикреплен AuthGuardService.canActivateChild? Почему он называется только с первой попытки?

Ответ 1

Вы упомянули, что pageRoute может иметь все дочерние приложения, поэтому файл маршрутизации должен содержать этот модуль.

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

Я предлагаю использовать AuthGuard только один раз. AuthGaurd следует использовать на модуле, содержащем другие модули или компоненты, а не быть самим компонентом входа.

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

app.route.ts

const routes: Routes = [
  {
    path: '',
    loadChildren: './pages/pages.module#PagesModule',
    canActivate: [AuthGuardService]
  },
  { path: 'login', loadChildren: './login/login.module#LoginModule' },

];

AuthGuard

canActivateChild(): boolean {
  if (this._authService.isAuthenticated()) {
      return true;
  }
  this._router.navigate(['/login']);
  return false;
}

Page.route.ts

const routes: Routes = [
  {
    path: '', component: PageComponent,
     children: [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'home', component: HomePageComponent },
  { path: 'contents', component: ContentsComponent },


     ]
  }
];

Если вы хотите отлаживать текущее условие маршрутизации, вы можете использовать Augury из интернет-магазина Chrome.