1

我尝试使用 firebase-auth 为 Angular 2 应用程序构建 AuthGuard,但存在一个问题。

应用程序加载后如果我因异步操作而登录AuthGuard返回。 最终效果是页面加载时返回 firstime和 then ,因此每次重定向到 signIn 页面而不是根页面。 我认为我只使用 *ngIf 来显示,如果用户没有登录,但这不是解决方案,因为每次 SignInComponent 都会在短时间内可见。 如何解决此问题不立即重定向到登录页面? 谢谢您的回答。false

AuthGuardfalsetrue

SignInComponent





身份验证服务

@Injectable()
export class AuthService {

  static UNKNOWN_USER = new AuthInfo(null);
  user: Observable<firebase.User>;
  authInfo$: BehaviorSubject<AuthInfo> = new BehaviorSubject<AuthInfo>(AuthService.UNKNOWN_USER);

  constructor(private afAuth: AngularFireAuth) {
    this.afAuth.authState.subscribe(
      auth => {
        if (auth) {
          const authInfo = new AuthInfo(auth.uid);
          this.authInfo$.next(authInfo);
        } else {
          this.authInfo$.next(AuthService.UNKNOWN_USER);
        }
      },
      err => {
        console.log(err);
      }
    );
  }
}

授权信息

export class AuthInfo {
  constructor(
    public $uid: string
  ) {

  }

  isLoggedIn() {
    return !!this.$uid;
  }
}

AuthGuard

@Injectable()
export class AuthGuard implements  CanActivate {

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

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.authService.authInfo$
      .map( authInfo => authInfo.isLoggedIn())
      .take(1)
      .do(allowed => {
        console.log('authguard: ' + allowed);
        if (!allowed) {
           this.router.navigate(['/signin']);
        }
    });
  }
}
4

1 回答 1

0

对不起,这个问题是重复的问题

我的解决方案是

身份验证服务

@Injectable()
export class AuthService {

  static UNKNOWN_USER = new AuthInfo(null);
  authInfo$: BehaviorSubject<AuthInfo> = new BehaviorSubject<AuthInfo>(AuthService.UNKNOWN_USER);

  constructor(private afAuth: AngularFireAuth) {}

  getAuthInfo(): Observable<AuthInfo> {
    return this.afAuth.authState.map(
      auth => {
        if (auth) {
          const authInfo = new AuthInfo(auth.uid);
          this.authInfo$.next(authInfo);
          return authInfo;
        } else {
          this.authInfo$.next(AuthService.UNKNOWN_USER);
          return AuthService.UNKNOWN_USER;
        }
      },
      err => {
        console.log(err);
      }
    );
  }

AuthGuard

@Injectable()
export class AuthGuard implements  CanActivate {

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

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {

    if (this.authService.authInfo$.getValue().isLoggedIn()) {
      return true;
    }

    return this.authService.getAuthInfo()
      .map( (authInfo: AuthInfo) => authInfo.isLoggedIn())
      .do(allowed => {
        if (!allowed) {
          this.router.navigate(['/signin']);
          return false;
        } else {
          return true;
        }
      }).take(1);
  }
}
于 2017-06-27T21:48:32.793 回答