Guard canActivate在实例化服务之前运行

问题描述 投票:0回答:2

这很可能是一个非常琐碎的问题,我只是从AngularJS背景中学习Angular 2+。

最简单的是,我正在我的angular 9应用程序中实施身份验证,并遇到了与警卫有关的问题。

authentication.service.ts服务中,我使用类型为user的BehaviourSubject,并使用以下公共库在localStorage中保存User对象:https://github.com/cyrilletuzi/angular-async-local-storage

在我的authentication.service构造函数中,我正在执行以下操作:

constructor(private request: RequestService, private storage: StorageMap) {
    this.storage.get('currentUser').subscribe((user: User) => {
      this.currentUserSubject = new BehaviorSubject<User>(user);
      this.currentUser = this.currentUserSubject.asObservable();
    });
  } 

和我的isAuthenticated方法:

isAuthenticated() {
    return this.currentUserSubject.value;
  }

然而,这很好用,因为storageMap是可观察到的,它只需要很少的时间就可以返回,因此,当我尝试检查用户在我的守护程序中是否已通过身份验证时:

canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    return this.authService.isAuthenticated();
  } 

不幸的是this.currentUserSubject未定义。因此,在authentication.service中的构造函数有机会正确实例化之前,防护功能已在运行。

将不胜感激地收到任何积分。

angular angular9 angular2-observables
2个回答
0
投票

canActivate方法必须返回Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree

据我所知您正在返回一个对象(用户)。

但是,在您的警卫下,您应该使用可观察的物体而不是主题。

canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> {
    return this.authService.currentUser.pipe(map(user => !!user));
  } 

!!运算符的双重否定(map)将使可观察到的返回一个布尔值。


0
投票

导航时会激活警卫,因此在导航到帖子登录页面之前,请确保已设置用户。

constructor(private authenticationService: AuthenticationService, private router: Router) {}

ngOnInit() {
    this.handleUserChange();
}

private handleUserChange(): void {
    this.authenticationService.currentUserSubject
    .pipe(filter(user => user)) // falsy value check
    .subscribe(user => 
    {
         // Navigate to post login
         this.router.navigate(['home-page']);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.