【问题标题】:Angular 12: canActivate Guard not working on page refreshAngular 12:canActivate Guard 在页面刷新时不起作用
【发布时间】:2021-09-11 06:24:25
【问题描述】:

我的 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 Service 尚未获取配置文件的时候,在刷新的情况下,Guard 检查太早。

你能帮我解决这个问题吗?

提前致谢!

【问题讨论】:

    标签: angular firebase angular-guards angular12


    【解决方案1】:

    确保您的守卫正在等待 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
              })
      }
    
    
    }
    

    【讨论】:

      【解决方案2】:

      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)
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-20
        • 2019-02-20
        • 2019-02-05
        • 1970-01-01
        • 2015-02-16
        • 2022-01-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多