路由守卫导致错误的路由导航行为

Routes Guards causing wrong Route Navigation behavior

我在尝试浏览不同路线时遇到问题。

我有两个不同的路由模块。

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 前缀和子路由 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;
}

When I navigate from app/home to app/contents it only goes to ContentsComponent after navigating two times. So, if I do two times this._router.navigate(['app/components']); it works, if I do it only one time, the route changes from app/home to app/route for 1ms and it returns to app/home, while if I do it a second time it changes route. While, if I'm in app/contents and try to navigate to app/home it changes route just fine.

isAuthenticated 工作正常。两个 authguards 都工作得很好,所以,如果我在未登录时尝试访问任何 app 子路由,我将被重定向到登录,如果我在登录时尝试访问 login我被重定向到 app/home.

我设法调试了一下,我注意到以下流程:

当然是第二种行为。

编辑

PreventLoggedInAccess.canActivate 中删除 this._router.navigate([/app/home]); 解决了问题

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

但是,我仍然不明白 为什么在导航到 app 子级时调用 PreventLoggedInAccess.canActivate,即使 AuthGuardService.canActivateChild 已附加到它?为什么只在第一次尝试时调用它?

您提到 pageRoute 可以拥有应用程序的所有子子项 所以它的路由文件应该包含那个模块。

因此可以正确使用延迟加载和守卫的概念。 我通过假设您的 pageRoute 模块是 App.

的子模块来回答这个问题

我建议只使用一次AuthGuard。 AuthGaurd 应该在包含其他模块或组件的模块上使用,而不是在登录组件本身上使用。

这里页面模块是懒加载的,需要authguard才能激活returns 真的 如果是假用户,将导航到登录。

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 },


     ]
  }
];

如果您想在当前路由条件下进行调试,您可以使用 Chrome 网上商店中的 Augury