1

我的 canActivate 守卫是这样工作的:如果当前(fire auth)用户有一个用户配置文件,那么他可以访问路由。否则,我会将他引导至个人资料创建页面。

这工作得很好,除非我刷新页面!

警卫:

export class UserProfileGuard implements CanActivate {

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

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    if (this.authService.userProfile) {
      return true;
    }

    this.router.navigate(['user/createprofile']).then();
    return false;
  }


}

认证服务:

export class AuthService implements OnDestroy {
  public userProfile: UserProfile | null = null;
  private subscription: Subscription | undefined;

  constructor(public fire: AngularFireAuth, private httpService: HttpHandlerService) {
    this.subscription = this.fire.authState.subscribe(fireAuthUser => {
      if (fireAuthUser) {
        this.httpService.getMyProfile().subscribe((profile: UserProfile) => {
            this.userProfile = profile;
          })
      }
    });
  }
}

因此,如果我在受保护的路线上并刷新页面,我总是会被发送到配置文件创建页面,即使配置文件存在。

我担心在 Auth 服务尚未获取配置文件的情况下,在刷新的情况下,警卫会过早检查。

你能给我一些关于如何解决这个问题的帮助吗?

提前致谢!

4

2 回答 2

0

canActivate 接受 Observable 作为返回类型。因此,您可以返回 Observable 而不是直接返回 true/false,也可以返回一个 UrlTree,而不是编写 router.navigate,它会在这种情况下自动重定向。

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    return this.authService.getUserAuth().pipe(
    map((authResponse) => {
       if(authResponse) {
          return true;
       }
       return this.router.createUrlTree(['user, 'createprofile']).toString()
    }),
    catchError(() => {
      return this.router.createUrlTree(['user, 'createprofile']).toString()
    }))
  }

在您的服务中,您可以添加一个方法来返回 auth observable。

userProfile = null;

getUserAuth: () => {
   if(userProfile) {
     return of(userProfile)
   }

   return this.fire.authState.pipe(switchMap((fireAuthUser) => {
     if(fireAuthUser) {
       return this.httpService.getMyProfile()
     }
     return throwError('No Auth User found!')
   }), tap((profile) => this.userProfile = profile)
}
于 2021-06-29T04:40:18.310 回答
0

确保您的警卫正在等待 API 获取数据。

export class UserProfileGuard implements CanActivate {

  constructor(private authService: AuthService, private router: Router, private httpService: YourService) { }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    return checkUser();
  }

  checkUser(): Observable<boolean> {
   this.httpService.getMyProfile().subscribe((profile: UserProfile) => {
            // Do your if the profile exists check
            return true if they have profile
            return false if they don't
          })
  }


}
于 2021-06-29T02:57:21.940 回答