守卫 children 条路线
Guard on children routes
我知道这个主题经常在 Whosebug 上被处理。
我参考了 Stack 上的几个帖子,但建议的解决方案对我不起作用。
例如this one
我第一次尝试使用 Guards 来限制对页面的访问,但它对 child 个页面不起作用。
我有一个包含 child 的卡车模块:
Truck
|_ truck-list
|_ truck-search
|_ truck-menu
|_ truck-details
我有卡车模块的路线文件:
RouterModule.forChild([
{path: 'list', component: TruckListComponent, canActivate: [TruckGuard]},
{path: 'search', component: TruckSearchComponent, canActivate: [TruckGuard]},
{path: 'details/:id', component: TruckDetailsComponent},
{path: 'menu', component: TruckMenuListComponent},
{path: 'menu/:id', component: TruckMenuListComponent},
{path: 'menu/add/:id', component: TruckMenuAddComponent},
])
和一个 app-routing 模块:
const appRoutes: Routes = [
{ path: '', component: HomeComponent},
{ path: 'app-forbidden', component: ForbiddenComponent},
{ path: 'Home', component: HomeComponent},
{ path: 'About', component: AboutComponent},
{ path: 'forbidden', component: ForbiddenComponent},
{ path: 'Login', component: LoginComponent},
{ path: 'Logout', component: LoginComponent},
{ path: 'confirmation-commande/:message', component: ConfirmationCommandeComponent},
{ path: 'orders', component: OrderListComponent},
{ path: 'truck/search', component: TruckSearchComponent},
{ path: 'SignUp/customer', component: UseraccountCreateCustomerComponent},
{ path: 'SignUp/truck', component: UseraccountCreateTruckComponent},
{ path: 'useraccount', loadChildren: () => import('./useraccount/useraccount.module').then(u => u.UserAccountModule)},
{ path: 'truck', loadChildren: () => import('./truck/truck.module').then(t => t.TruckModule)},
{path: 'location', component: TruckLocationComponent},
{ path: '500', component: InternalServerComponent },
{ path: '', redirectTo: '/home', pathMatch: 'full' }
];
...
我还创建了一个 Truck.guard.ts 文件来管理卡车模块的路线:
export class TruckGuard implements CanActivate, CanActivateChild {
constructor(private authService: AuthService, private route: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url = window.location.pathname;
if((url == '/truck') && this.authService.isCustomer()){
return true;
}
else{
this.route.navigate(['app-forbidden']);
return false;
}
}
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url = window.location.pathname;
if((url == '/truck/list') && this.authService.isCustomer()){
return true;
}
else if((url == '/truck/search') && this.authService.isCustomer()){
return true;
}
else if((url == '/Login') && this.authService.isCustomer()){
return true;
}
else{
this.route.navigate(['app-forbidden']);
return false;
}
}
}
唯一可行的路径是 truck/list
。他很好地重定向到禁止页面。
其他的都不行。
我不明白为什么。我如何使用 canActivate 和 canActivateChild。
提前感谢您的帮助。
你做错了几件事。
truck/list 起作用的原因是因为您在其上应用了 canActivate 而不是此处的其余部分
{path: 'list', component: TruckListComponent, canActivate: [TruckGuard]},
并且在您的 canActivate 中,您仅在此处满足 truck/list
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url = window.location.pathname;
if((url == '/truck') && this.authService.isCustomer()){
return true;
}
else{
this.route.navigate(['app-forbidden']);
return false;
}
}
- 其他人不工作的原因是因为你没有将 canActivateChild 应用到父模块。
像这样向 appRoute 添加一个 canActivateChild
const appRoutes: Routes = [
{ path: '', component: HomeComponent},
{ path: 'app-forbidden', component: ForbiddenComponent},
{ path: 'Home', component: HomeComponent},
{ path: 'About', component: AboutComponent},
{ path: 'forbidden', component: ForbiddenComponent},
{ path: 'Login', component: LoginComponent},
{ path: 'Logout', component: LoginComponent},
{ path: 'confirmation-commande/:message', component: ConfirmationCommandeComponent},
{ path: 'orders', component: OrderListComponent},
{ path: 'truck/search', component: TruckSearchComponent},
{ path: 'SignUp/customer', component: UseraccountCreateCustomerComponent},
{ path: 'SignUp/truck', component: UseraccountCreateTruckComponent},
{ path: 'useraccount', loadChildren: () =>
import('./useraccount/useraccount.module').then(u => u.UserAccountModule)},
// Truck module Your canActivateChild comes here
{ path: 'truck', loadChildren: () => import('./truck/truck.module').then(t=> t.TruckModule)}, canActivateChild:TruckGuard // <<< HERE
{path: 'location', component: TruckLocationComponent},
{ path: '500', component: InternalServerComponent },
{ path: '', redirectTo: '/home', pathMatch: 'full' }
];
最后解决办法是在app中添加canActivateChild-module.ts:
{ path: 'truck', loadChildren: () => import('./truck/truck.module').then(t => t.TruckModule), canActivateChild: [TruckGuard]},
并在防护文件中使用 state: RouterStateSnapshot
代替 window.location.pathname
测试 url,如下所示:
if((state.url == '/truck/list') && this.authService.isCustomer()){
return true;
}
else if((state.url == '/truck/search') && this.authService.isCustomer()){
return true;
}
else if((state.url == '/truck/menu') && this.authService.isCustomer()){
return true;
}
else if((state.url == '/truck/menu/' + childRoute.params['id']) && this.authService.isCustomer()){
return true;
}
else if((state.url == '/truck/details/' + childRoute.params['id']) && this.authService.isCustomer()){
return true;
}
else if((state.url == '/Login') && this.authService.isCustomer()){
return true;
}
else{
this.route.navigate(['app-forbidden']);
return false;
}
我知道这个主题经常在 Whosebug 上被处理。
我参考了 Stack 上的几个帖子,但建议的解决方案对我不起作用。
例如this one
我第一次尝试使用 Guards 来限制对页面的访问,但它对 child 个页面不起作用。
我有一个包含 child 的卡车模块:
Truck
|_ truck-list
|_ truck-search
|_ truck-menu
|_ truck-details
我有卡车模块的路线文件:
RouterModule.forChild([
{path: 'list', component: TruckListComponent, canActivate: [TruckGuard]},
{path: 'search', component: TruckSearchComponent, canActivate: [TruckGuard]},
{path: 'details/:id', component: TruckDetailsComponent},
{path: 'menu', component: TruckMenuListComponent},
{path: 'menu/:id', component: TruckMenuListComponent},
{path: 'menu/add/:id', component: TruckMenuAddComponent},
])
和一个 app-routing 模块:
const appRoutes: Routes = [
{ path: '', component: HomeComponent},
{ path: 'app-forbidden', component: ForbiddenComponent},
{ path: 'Home', component: HomeComponent},
{ path: 'About', component: AboutComponent},
{ path: 'forbidden', component: ForbiddenComponent},
{ path: 'Login', component: LoginComponent},
{ path: 'Logout', component: LoginComponent},
{ path: 'confirmation-commande/:message', component: ConfirmationCommandeComponent},
{ path: 'orders', component: OrderListComponent},
{ path: 'truck/search', component: TruckSearchComponent},
{ path: 'SignUp/customer', component: UseraccountCreateCustomerComponent},
{ path: 'SignUp/truck', component: UseraccountCreateTruckComponent},
{ path: 'useraccount', loadChildren: () => import('./useraccount/useraccount.module').then(u => u.UserAccountModule)},
{ path: 'truck', loadChildren: () => import('./truck/truck.module').then(t => t.TruckModule)},
{path: 'location', component: TruckLocationComponent},
{ path: '500', component: InternalServerComponent },
{ path: '', redirectTo: '/home', pathMatch: 'full' }
];
...
我还创建了一个 Truck.guard.ts 文件来管理卡车模块的路线:
export class TruckGuard implements CanActivate, CanActivateChild {
constructor(private authService: AuthService, private route: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url = window.location.pathname;
if((url == '/truck') && this.authService.isCustomer()){
return true;
}
else{
this.route.navigate(['app-forbidden']);
return false;
}
}
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url = window.location.pathname;
if((url == '/truck/list') && this.authService.isCustomer()){
return true;
}
else if((url == '/truck/search') && this.authService.isCustomer()){
return true;
}
else if((url == '/Login') && this.authService.isCustomer()){
return true;
}
else{
this.route.navigate(['app-forbidden']);
return false;
}
}
}
唯一可行的路径是 truck/list
。他很好地重定向到禁止页面。
其他的都不行。
我不明白为什么。我如何使用 canActivate 和 canActivateChild。
提前感谢您的帮助。
你做错了几件事。
truck/list 起作用的原因是因为您在其上应用了 canActivate 而不是此处的其余部分
{path: 'list', component: TruckListComponent, canActivate: [TruckGuard]},
并且在您的 canActivate 中,您仅在此处满足 truck/list
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url = window.location.pathname;
if((url == '/truck') && this.authService.isCustomer()){
return true;
}
else{
this.route.navigate(['app-forbidden']);
return false;
}
}
- 其他人不工作的原因是因为你没有将 canActivateChild 应用到父模块。
像这样向 appRoute 添加一个 canActivateChild
const appRoutes: Routes = [
{ path: '', component: HomeComponent},
{ path: 'app-forbidden', component: ForbiddenComponent},
{ path: 'Home', component: HomeComponent},
{ path: 'About', component: AboutComponent},
{ path: 'forbidden', component: ForbiddenComponent},
{ path: 'Login', component: LoginComponent},
{ path: 'Logout', component: LoginComponent},
{ path: 'confirmation-commande/:message', component: ConfirmationCommandeComponent},
{ path: 'orders', component: OrderListComponent},
{ path: 'truck/search', component: TruckSearchComponent},
{ path: 'SignUp/customer', component: UseraccountCreateCustomerComponent},
{ path: 'SignUp/truck', component: UseraccountCreateTruckComponent},
{ path: 'useraccount', loadChildren: () =>
import('./useraccount/useraccount.module').then(u => u.UserAccountModule)},
// Truck module Your canActivateChild comes here
{ path: 'truck', loadChildren: () => import('./truck/truck.module').then(t=> t.TruckModule)}, canActivateChild:TruckGuard // <<< HERE
{path: 'location', component: TruckLocationComponent},
{ path: '500', component: InternalServerComponent },
{ path: '', redirectTo: '/home', pathMatch: 'full' }
];
最后解决办法是在app中添加canActivateChild-module.ts:
{ path: 'truck', loadChildren: () => import('./truck/truck.module').then(t => t.TruckModule), canActivateChild: [TruckGuard]},
并在防护文件中使用 state: RouterStateSnapshot
代替 window.location.pathname
测试 url,如下所示:
if((state.url == '/truck/list') && this.authService.isCustomer()){
return true;
}
else if((state.url == '/truck/search') && this.authService.isCustomer()){
return true;
}
else if((state.url == '/truck/menu') && this.authService.isCustomer()){
return true;
}
else if((state.url == '/truck/menu/' + childRoute.params['id']) && this.authService.isCustomer()){
return true;
}
else if((state.url == '/truck/details/' + childRoute.params['id']) && this.authService.isCustomer()){
return true;
}
else if((state.url == '/Login') && this.authService.isCustomer()){
return true;
}
else{
this.route.navigate(['app-forbidden']);
return false;
}