角度:运行canActivate每个路线变化

角度:运行canActivate每个路线变化

问题描述:

我最近被卡住角度的警卫。 CanActive只在加载页面时运行一次,并且不在被保护的路由内的路由更改上运行。我认为这已经改变了,因为它用于每次更改。从我在论坛中阅读的内容中,我应该使用CanActivateChild。事情是,我们的应用程序由几个模块组成,它们有几个路由后代,当我在根模块中使用CanActivateChild时,在更改路由时会多次调用它。角度:运行canActivate每个路线变化

我觉得为每个孩子分配一个警卫是愚蠢的,因为对于AppModule,这些懒惰的加载子模块应该只是'黑盒子',我想要定义所有这些模块应该被保护。

export const routes: Routes = [ 
    { 
    path: '404', 
    component: NotFoundComponent 
    }, 
    { 
    path: '', 
    canActivate: [AuthGuard], 
    component: FullLayoutComponent, 
    data: { 
     title: 'Home' 
    }, 
    children: [ 
     { 
     path: 'administration', 
     loadChildren: './administration/administration.module#AdministrationModule' 
     }, 
     { 
     path: 'settings', 
     loadChildren: './settings/settings.module#SettingsModule' 
     } 
    ] 
    }, 
    { 
    path: '', 
    loadChildren: './account/account.module#AccountModule' 
    }, 
    { 
    path: '**', 
    redirectTo: '404' 
    } 
]; 

有没有解决方法?或者你认为这是安全方面的“不是问题”?

谢谢大家。

面对同样的问题,我在问题上找到的所有问题都很少有关于Github的封闭问题,Angular devs声明这种行为是“按设计”。

所以我最后做的是在app.component在导航事件订阅和射击AuthGuard检查有:

constructor(
    private router: Router, 
    private route: ActivatedRoute, 
    private authGuard: AuthGuard, 
) {} 

ngOnInit() { 
    this.router.events 
    .subscribe(event => { 
     if (event instanceof RoutesRecognized) { 
     this.guardRoute(event); 
     } 
    })); 
} 

private guardRoute(event: RoutesRecognized): void { 
    if (this.isPublic(event)) { 
    return; 
    } 

    if (!this.callCanActivate(event, this.authGuard)) { 
    return; 
    } 
} 

private callCanActivate(event: RoutesRecognized, guard: CanActivate) { 
    return guard.canActivate(this.route.snapshot, event.state); 
} 

private isPublic(event: RoutesRecognized) { 
    return event.state.root.firstChild.data.isPublic; 
} 

AuthGuard是相当标准:

@Injectable() 
export class AuthGuard implements CanActivate{ 

    constructor(private auth: AuthService, private router: Router) { } 

    canActivate(): Promise<boolean> { 
    return this.auth.isLoggedInPromise() 
     .then(isLoggedIn => { 
     if (!isLoggedIn) { 
      this.router.navigate(["/login"]); 
     } 
     return isLoggedIn; 
     }); 
    } 
    } 

和公共路线应配置像这样:

{ 
    path: "login", 
    component: LoginComponent, 
    data: { isPublic: true } 
} 

这种实现的优点是每个东西被默认保护,公共路线应该明确配置,这将减少不保护某些路线的可能性。还会将此重构为某种服务,以便能够跨多个应用程序使用它。

this answer的启发。

+0

是的,我发现很相似。 “按设计”。我发现你的答案是迄今为止最好的解决方案,所以谢谢你! –