我有一个带有延迟加载模块的角度4.3.6应用程序 . 这是一个部分根路由器:
const routes: Routes = [
{ path: '', redirectTo: 'fleet', pathMatch: 'full' },
{
path: '',
component: AppComponent,
canActivate: [AuthenticationGuard],
children: [
{
path: 'fleet',
loadChildren: "./modules/fleet.module",
canActivate: [AuthenticationGuard]
},
{
path: 'password/set',
loadChildren: "./modules/chooseNewPassword.module",
canActivate: [ChoosePasswordGuard]
}
]
}
]
// Exports RouterModule.forRoot(routes, { enableTracing: true });
我的子路由器在这两个示例模块中:
舰队:
RouterModule.forChild([
{
path: '',
component: FleetComponent,
canActivate: [AuthenticationGuard]
}
]);
选择新密码:
RouterModule.forChild([
{
path: '',
component: ChooseNewPasswordComponent,
canActivate: [ChoosePasswordGuard]
}
]);
AuthenticationGuard
调用一个如下所示的方法:
return this.getUserSession().map((userSession: UserSession) => {
if (userSession && userSession.ok) {
return true;
}
else if (userSession && userSession.expired) {
this.router.navigate(['password/set'])
.catch((e: Error) => console.error(e));
return true;
}
else {
window.location.replace('/');
return false;
}
}
因此,如果用户的会话正常,则会激活路由 . 如果用户的密码已过期,则会将用户重定向到选择新密码模块 . 如果没有会话,则重定向到登录 .
ChoosePasswordGuard
做了类似的事情,但只保护选择新密码组件(一般使用不同的工具来设置密码):
return this.getUserSession().map((userSession: UserSession) => {
if (userSession) {
return userSession.expired;
}
else {
return false;
}
});
这在模块拆分之前有效 .
现在,我陷入了重定向循环 . 在路由器跟踪的情况下,我会观察以下顺序 . 用户登录并 AuthenticationGuard
更正重定向到/ password / set模块,并切换到 ChooseNewPasswordGuard
:
-
NavigationStart(id:4,url:'/password/set')
-
RoutesRecognized {id:4,url:"/password/set",urlAfterRedirects:"/password/set",state:RouterStateSnapshot}
-
GuardsCheckStart {id:4,url:"/password/set",urlAfterRedirects:UrlTree,state:RouterStateSnapshot}
-
GuardsCheckEnd {id:4,url:"/password/set",urlAfterRedirects:UrlTree,state:RouterStateSnapshot, shouldActivate: true }
-
NavigationCancel {id:4,url:"/password/set", reason: "" }
并且这个循环重复 .
(如果我用 return Observable.of(true);
替换整个ChooseNewPasswordGuard,它也会重复)
编辑:即使我在URL栏中提供 /#/password/set
,我也被重定向到根页面( /
)...
Questions:
-
由于模块是延迟加载的,我在路由器或防护装置中做错了什么来强制执行此循环?我特别感到困惑的是
shouldActivate: true
,接着是NavigationCancel reason: ""
. -
这是否与我直接在AuthenticationGuard中重定向的事实有关,现在这个防护应用于我的主空根路径(
{ path: '', redirectTo: 'fleet', pathMatch: 'full' }
)它's always called and redirects, even once I'已设置路径? -
我是否真的需要在我的子路线和我的根路线中重复
canActivate
守卫? -
像往常一样,欢迎提出任何其他意见 .
1 回答
问题是我过度应用
AuthenticationGuard
:它不应该应用于顶级AppComponent,因为它总是会重定向到Choose New Password模块,即使它正在加载该模块 .我的根
routes
应该是这样的:(我欢迎并乐意接受更好的解释或更好的AuthenticationGuard模式 . )