admin管理员组文章数量:1305899
I'm encountering a strange behaviour (or maybe a wanted one). I have an Angular application where all the modules are lazy loaded.
On one module I have a guard that checks if the decoded user from the JWT is a system admin. If so, the user shall proceed to the section, otherwise it will be redirected in dashboard.
The strange thing is that this thing works only upon the first module load. Then, if I try to logout and access with a user that is not as system admin, the CanLoad guard does not trigger.
I've also tried to implement in the same guard the (CanActivate and CanActivateChild) interfaces, and put the guard on the app-routing.module.ts
and on the feature-routing.module.ts
modules, respectively on the CanLoad, CanActivate, and CanActivateChild properties of the modules.
The CanActivate CanActivateChild methods never gets called. Never.
While the CanLoad placed on the app-routing.module.ts
is called just once.
Here's the is-sys-adm.guard.ts
file:
export class SFWIsSysAdmGuard implements CanLoad, CanActivate, CanActivateChild {
public constructor(
private readonly accessSvc: SFWAuthService,
private readonly toastSvc: NbToastrService,
private readonly translateSvc: TranslateService,
private readonly navigationSvc: NavigationService,
) { }
public canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
console.log('Can activate child hit');
return this.canLoad(undefined, undefined);
}
public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
console.log('Can activate hit');
return this.canLoad(undefined, undefined);
}
public canLoad(route: Route, segments: UrlSegment[]): boolean {
console.log('Can load hit');
const decodedUser = this.accessSvc.decodedUser;
if (!!decodedUser && !!decodedUser.isSystemAdmin) {
return true;
}
this.navigationSvc.goToDashboard();
this.toastSvc.warning(
this.translateSvc.instant('framework.guards.adm_only.access_denied'),
this.translateSvc.instant('mon.access_to_section_denied_ttl'),
);
return false;
}
}
Here's the app-routing.module.ts
file:
const routes: Routes = [
{
path: '',
redirectTo: `/${AppRoutes.access}`,
pathMatch: 'full'
},
{
path: AppRoutes.dashboard,
loadChildren: () => import('./dashboard/dashboard.module').then(mod => mod.DashboardModule)
},
{
path: AppRoutes.pins,
loadChildren: () => import('./pins/pins.module').then(mod => mod.PinsModule)
},
{
path: AppRoutes.pinTypes,
loadChildren: () => import('./pin-types/pin-types.module').then(mod => mod.PinTypesModule)
},
{
path: AppRoutesanizationPickup,
loadChildren: () => import('./organization-picker/organization-picker.module').then(mod => mod.OrganizationPickerModule)
},
{
path: AppRoutes.access,
loadChildren: () => import('./access/access.module').then(mod => mod.AccessModule)
},
{
path: AppRoutes.tourism,
loadChildren: () => import('./tourism/tourism.module').then(mod => mod.TourismModule)
},
{
path: AppRoutes.security,
canLoad: [SFWIsSysAdmGuard],
loadChildren: () => import('./security/security.module').then(mod => mod.SecurityModule)
},
{
path: AppRoutes.notFound,
loadChildren: () => import('./not-found/not-found.module').then(mod => mod.NotFoundModule)
},
{
path: '**',
redirectTo: '/404'
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Last but not least: feature-routing.module.ts
file:
const routes: Routes = [
{
path: '',
canActivate: [SFWIsSysAdmGuard],
ponent: SecurityComponent,
children: [
{
path: 'tokens-generator',
canActivateChild: [SFWIsSysAdmGuard],
ponent: TokensGeneratorComponent
},
]
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class SecurityRoutingModule { }
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class SecurityRoutingModule { }
Before you ask, I've also tried to put the guard separately in a CanActivate, CanActivateChild, CanLoad to try to prevent any conflict (which shouldn't exist if I've understand the docs.)
Am I missing something? Is is a wanted behaviour or should I open a bug on the official repo?
Thank to anyone willing to spend time on this <3
I'm encountering a strange behaviour (or maybe a wanted one). I have an Angular application where all the modules are lazy loaded.
On one module I have a guard that checks if the decoded user from the JWT is a system admin. If so, the user shall proceed to the section, otherwise it will be redirected in dashboard.
The strange thing is that this thing works only upon the first module load. Then, if I try to logout and access with a user that is not as system admin, the CanLoad guard does not trigger.
I've also tried to implement in the same guard the (CanActivate and CanActivateChild) interfaces, and put the guard on the app-routing.module.ts
and on the feature-routing.module.ts
modules, respectively on the CanLoad, CanActivate, and CanActivateChild properties of the modules.
The CanActivate CanActivateChild methods never gets called. Never.
While the CanLoad placed on the app-routing.module.ts
is called just once.
Here's the is-sys-adm.guard.ts
file:
export class SFWIsSysAdmGuard implements CanLoad, CanActivate, CanActivateChild {
public constructor(
private readonly accessSvc: SFWAuthService,
private readonly toastSvc: NbToastrService,
private readonly translateSvc: TranslateService,
private readonly navigationSvc: NavigationService,
) { }
public canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
console.log('Can activate child hit');
return this.canLoad(undefined, undefined);
}
public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
console.log('Can activate hit');
return this.canLoad(undefined, undefined);
}
public canLoad(route: Route, segments: UrlSegment[]): boolean {
console.log('Can load hit');
const decodedUser = this.accessSvc.decodedUser;
if (!!decodedUser && !!decodedUser.isSystemAdmin) {
return true;
}
this.navigationSvc.goToDashboard();
this.toastSvc.warning(
this.translateSvc.instant('framework.guards.adm_only.access_denied'),
this.translateSvc.instant('mon.access_to_section_denied_ttl'),
);
return false;
}
}
Here's the app-routing.module.ts
file:
const routes: Routes = [
{
path: '',
redirectTo: `/${AppRoutes.access}`,
pathMatch: 'full'
},
{
path: AppRoutes.dashboard,
loadChildren: () => import('./dashboard/dashboard.module').then(mod => mod.DashboardModule)
},
{
path: AppRoutes.pins,
loadChildren: () => import('./pins/pins.module').then(mod => mod.PinsModule)
},
{
path: AppRoutes.pinTypes,
loadChildren: () => import('./pin-types/pin-types.module').then(mod => mod.PinTypesModule)
},
{
path: AppRoutesanizationPickup,
loadChildren: () => import('./organization-picker/organization-picker.module').then(mod => mod.OrganizationPickerModule)
},
{
path: AppRoutes.access,
loadChildren: () => import('./access/access.module').then(mod => mod.AccessModule)
},
{
path: AppRoutes.tourism,
loadChildren: () => import('./tourism/tourism.module').then(mod => mod.TourismModule)
},
{
path: AppRoutes.security,
canLoad: [SFWIsSysAdmGuard],
loadChildren: () => import('./security/security.module').then(mod => mod.SecurityModule)
},
{
path: AppRoutes.notFound,
loadChildren: () => import('./not-found/not-found.module').then(mod => mod.NotFoundModule)
},
{
path: '**',
redirectTo: '/404'
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Last but not least: feature-routing.module.ts
file:
const routes: Routes = [
{
path: '',
canActivate: [SFWIsSysAdmGuard],
ponent: SecurityComponent,
children: [
{
path: 'tokens-generator',
canActivateChild: [SFWIsSysAdmGuard],
ponent: TokensGeneratorComponent
},
]
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class SecurityRoutingModule { }
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class SecurityRoutingModule { }
Before you ask, I've also tried to put the guard separately in a CanActivate, CanActivateChild, CanLoad to try to prevent any conflict (which shouldn't exist if I've understand the docs.)
Am I missing something? Is is a wanted behaviour or should I open a bug on the official repo?
Thank to anyone willing to spend time on this <3
Share Improve this question asked Aug 29, 2019 at 9:51 CaiusCaius 2,2647 gold badges34 silver badges53 bronze badges1 Answer
Reset to default 10The CanLoad
determines whether the lazy module can be loaded from the server. After it has been loaded, this will not be checked again (unless you press F5). I guess you need to declare it twice, once in CanLoad
(if you don't want the code to be loaded at all), and CanActivate
, if you want to restrict access.
{
path: AppRoutes.security,
canLoad: [SFWIsSysAdmGuard],
canActivate: [SFWIsSysAdmGuard],
loadChildren: () => import('./security/security.module').then(mod => mod.SecurityModule)
},
本文标签: javascriptAngular CanLoad guard triggers only once upon first lazy loadStack Overflow
版权声明:本文标题:javascript - Angular CanLoad guard triggers only once upon first lazy load? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741808854a2398672.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论