首页 > 解决方案 > 使用服务检查用户是否经过身份验证,守卫不起作用

问题描述

我实现了一个 firebase 身份验证页面。所以我设置了一个service UserService像这样的Angular:

export class UserService {

  public authenticated: boolean;
  public error: any;
  public currentUser: User;

  constructor(public afAuth: AngularFireAuth) {
    this.authenticated = false;
    this.afAuth.authState.subscribe(authenticated => {
      if (authenticated) {
        this.authenticated = true;
      }
    });
  }

  async loginWithGoogle() {
    try {
      const result = await this.afAuth.auth.signInWithPopup(new auth.GoogleAuthProvider());
      this.authenticated = true;
      console.log(result.user);
    } catch (e) {
      this.error = e;
    }
  }

  async loginWithFacebook() {
    try {
      await this.afAuth.auth.signInWithPopup(new auth.FacebookAuthProvider());
      this.authenticated = true;
    } catch (e) {
      this.error = e;
    }
  }

}

这似乎工作正常。但是当我尝试访问受以下守卫保护的路由时:

export class AuthenticatedGuard implements CanActivate {
  constructor(public userService: UserService, private router: Router) { }
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    alert(this.userService.authenticated);
    if (this.userService.authenticated) {
      return true;
    }
    this.router.navigate(['/']);
    return false;
  }
}

this.userService.authenticated总是false

有一个更好的方法吗?如果不是,这里有什么问题?也许authenticated应该是Observable守卫订阅?

标签: angularfirebasefirebase-authentication

解决方案


我会使用方法 getauthenticated()而不是使用布尔属性。您的布尔属性将始终具有相同的值。尝试添加以下方法:

get authenticated(){
  if(this.afAuth.auth.currentUser) {
  this.currentUser = this.afAuth.auth.currentUser
  return true;
  }
  else {
    return false
  };    
}

然后使用this.userService.authenticated()而不是this.userService.authenticated

编辑

我还将您的UserService的构造函数更改为:

constructor(public afAuth: AngularFireAuth) {
    this.authenticated = this.authenticated()
  }

您必须记住,您需要使用函数 authenticated() 而不是 boolean authenticated。这是因为尽管类是单例,但不同的组件不会自动通知变量的变化。


推荐阅读