【问题标题】:Routes Guards causing wrong Route Navigation behaviorRoutes Guards 导致错误的 Route Navigation 行为
【发布时间】:2018-02-21 23:46:21
【问题描述】:

我在尝试通过不同路线导航时遇到问题。

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

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

当我从 app/home 导航到 app/contents 时,它只会在导航两次后转到 ContentsComponent。所以,如果我做两次this._router.navigate(['app/components']); 它可以工作,如果我只做一次,路线会从app/home 更改为app/route 1ms,然后返回到app/home,而如果我再做一次它改变了路线。 同时,如果我在app/contents 并尝试导航到app/home,它会更改路线就好了。

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

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

  • 第一次尝试 - app/home -> app/contents:
    • navigate(['app/contents']) 被调用
    • PreventLoggedInAccess.canActivate 被调用
    • AuthGuardService.canActivateChild 被调用
  • 第二次尝试 - app/home -> app/contents
    • navigate(['app/contents']) 被调用
    • AuthGuardService.canActivateChild 被调用

当然,预期的行为是第二​​种。

编辑

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

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

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

【问题讨论】:

  • 尝试使用enableTracing 看看发生了什么:RouterModule.forRoot(routes, { useHash : true, enableTracing: true });
  • 还值得检查一下 isAuthenticated() 第一次和第二次所说的内容。
  • 你的模块是什么样的?我想知道合并路线的顺序是否导致问题?

标签: angular typescript angular-routing angular-router angular-router-guards


【解决方案1】:

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

因此可以正确使用延迟加载和守卫的概念。 我已经通过假设您的 pageRoute 模块是 App 的子模块来回答这个问题。

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

这里的页面模块是延迟加载的,只有authguard返回才能激活 真的 如果出现虚假用户将导航到登录。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    • 2021-12-30
    • 2021-12-20
    相关资源
    最近更新 更多