【发布时间】:2020-03-30 10:24:49
【问题描述】:
我正在尝试使用AuthGuard 中间件保护经过身份验证的路由。当我将此中间件实现为路由时。激活守卫后,这些路线不起作用。
应用路由模块
const routes: Routes = [
{
path: 'posts',
canLoad: [AuthGuardMiddleware],
loadChildren: () => import('./modules/posts/posts.module').then(m => m.PostsModule)
},
{
path: 'users',
canLoad: [AuthGuardMiddleware],
loadChildren: () => import('./modules/users/users.module').then(m => m.UsersModule)
}
];
@NgModule({
imports: [RouterModule.forRoot(routes, {
preloadingStrategy: PreloadAllModules
})],
exports: [RouterModule]
})
和 AuthGuardMiddleware
@Injectable({
providedIn: 'root'
})
export class AuthGuardMiddleware implements CanActivate, CanLoad {
constructor(private authService: AuthService, private router: Router) {
}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean | UrlTree> {
return this.authService.user.pipe(map(user => {
if (user) {
return true;
}
return this.router.createUrlTree(['/login']);
}));
}
canLoad(route: Route, segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean {
return this.authService.user.pipe(map(user => {
if (user) {
return true;
}
this.router.navigate(['/']);
return false;
}));
}
}
我该如何解决? 注意:AuthService::user 类型为 BehaviorSubject 初始化为 null
更新
我意识到当我清理我的应用程序组件并删除条件路由器出口时,一切都开始正常工作。我仍然不知道究竟是什么导致了这个错误。
应用组件
export class AppComponent implements OnInit {
currentUrl: string;
isAuthRoute = false;
constructor(private router: Router) {
}
ngOnInit() {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
this.currentUrl = event.url;
this.isAuthRoute = ['/login', '/register']
.indexOf(this.currentUrl) !== -1;
}
});
}
}
应用组件视图
<div *ngIf="!isAuthRoute">
<div class="row page-wrapper">
<div class="col-md-3 col-md-pull-9">
<app-sidebar></app-sidebar>
</div>
<div class="col-md-9 col-md-push-3 content-area">
<router-outlet></router-outlet>
</div>
</div>
</div>
<div style="height: 80vh" class="d-flex justify-content-center align-items-center" *ngIf="isAuthRoute">
<router-outlet ></router-outlet>
</div>
【问题讨论】:
-
根据您的解决方案,也许您应该将显示/隐藏路由器插座的逻辑传递给延迟加载模块(守卫将决定是否可以加载/激活它)。
router-outlet从一开始就需要在那里吗?我听说过 angular-dart 有这样的问题。但是......在得出这个结论之前,请尝试添加一个额外的模块,该模块可以作为您应用程序所有其余部分的外壳,并且只会为授权用户加载/激活。它相当于您的*ngIf逻辑。 -
其实这里的 ngIf 逻辑只是为了显示一页登录页面并隐藏侧边栏。所有经过身份验证的组件都封装为一个单独的模块。
-
是的,我明白了……我建议您将该逻辑转移到一个新的延迟加载 shell 模块的保护中。这将解决问题如果它确实与动态创建的
router-outlet有关。 -
看看this angular-dart issue 显然与你所拥有的相似。
-
@julianobrasil 它也可以,谢谢你的所有建议,但我会接受 PierreDuc 的回答
标签: angular