![](/img/trans.png)
[英]Angular route guard doesn't render dashboard even if a cognitoUser is present
[英]Components doesn't render after guard, angular 9
我正在嘗試使用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]
})
和 AuthGuard 中間件
@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>
您的AuthService.user
返回一個 Observable 流並且它永遠不會完成。 據我所知, canLoad
和canActivate
需要一個完整的Observable
。 您可以使用take(1)
運算符來實現:
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean | UrlTree> {
return this.authService.user.pipe(
map(user => {
if (user) {
return true;
}
return this.router.createUrlTree(['/login']);
}),
take(1)
);
}
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;
}),
take(1)
);
}
我想這可能發生的另一個原因是因為您正在使用PreloadAllModules
策略。 這將立即加載所有模塊,但我想這是在用戶尚未登錄時完成的,因此守衛將返回 false 並且模塊不會加載,也不會重試。
因此,如果您使用PreloadAllModules
,您需要重新考慮是否要以這種方式使用canLoad
保護。 也許canActivate
守衛就足夠了。
您還可以實現自定義預加載策略,以某種方式等待用戶登錄加載它
有了關於條件路由器插座的附加信息,這是有道理的,因為首先組件將放置在一個router-outlet
,但是在路由完成后,另一個router-outlet
變得可見,但沒有放置任何東西在那里:)。 你可以通過使用ngTemplateOutlet
指令來更新你的模板來規避這個:
<ng-template #outlet>
<router-outlet ></router-outlet>
</ng-template>
<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">
<ng-component [ngTemplateOutlet]="outlet"></ng-component>
</div>
</div>
</div>
<div style="height: 80vh" class="d-flex justify-content-center align-items-center" *ngIf="isAuthRoute">
<ng-component [ngTemplateOutlet]="outlet"></ng-component>
</div>
通過這種方式,您可以確保AppComponent
中只放置一個router-outlet
,這是應該完成的方式
我看不到您在 AppRoutingModule 中使用 AuthGuard 的位置。
嘗試將其應用於任何路線,例如:
{
path: 'posts',
canLoad: [AuthGuard],
loadChildren: () => import('./modules/posts/posts.module').then(m => m.PostsModule),
},
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.