【问题标题】:Angular4 canActivate and google firebaseAngular4 canActivate 和 google firebase
【发布时间】:2018-03-29 00:45:09
【问题描述】:

在使用 firebase 时,我的 Angular 4 应用和 canActivate 防护出现问题。

我有这个服务 AuthService 链接到 firebase。

@Injectable()
export class AuthService {

  authState: any = null;

  constructor(private afAuth: AngularFireAuth,private db: AngularFireDatabase,private router:Router) {
    this.afAuth.authState.subscribe((auth) => {
      this.authState = auth
    });

    this.afAuth.auth.onAuthStateChanged(user => {
      if(user){
        console.log('user signed in');
      }
      else{
        this.anonymousLogin();
      }
    })
  }

  get authenticated(): boolean {
    return this.authState !== null;
  }

  get currentUser(): any {
    return this.authenticated ? this.authState : null;
  }

  get currentUserAnonymous(): boolean {
    return this.authenticated ? this.authState.isAnonymous : false;
  }

  //// Google Auth ////
  googleLogin() {
    const provider = new firebase.auth.GoogleAuthProvider()
    return this.socialSignIn(provider);
  }
  private socialSignIn(provider) {
    return this.afAuth.auth.signInWithPopup(provider)
      .then((credential) =>  {
          this.authState = credential.user
      })
      .catch(error => console.log(error));
  }

  //// Anonymous Auth ////
  anonymousLogin() {
    return this.afAuth.auth.signInAnonymously()
    .then((user) => {
      this.authState = user
    })
    .catch(error => console.log(error));
  }

  //// Email/Password Auth ////
  emailLogin(email:string, password:string) {
    return this.afAuth.auth.signInWithEmailAndPassword(email, password)
      .then((user) => {
        this.authState = user
      })
      .catch(error => console.log(error));
  }

  //// Sign Out ////
  signOut(): void {
    this.afAuth.auth.signOut();
    this.router.navigate(['/'])
  }
}

这是我的后卫

@Injectable()
export class AuthGuard implements CanActivate {

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

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
      if(this.auth.authState && !this.auth.currentUserAnonymous){
        console.log('User is staff');
        return true;
      }
      else{
        console.log(this.auth.authState);
        console.log(this.auth.currentUserAnonymous);
        console.log('User is not staff')
        this.router.navigate(['/']);
        return false;
      }
  }
}

当您在用户登录时使用来自另一个组件的链接导航到受保护组件时,保护工作正常,但是当您尝试使用地址栏直接转到受保护组件时,它会记录以下内容

auth.guard.ts:20 null  <-- this.auth.authState
auth.guard.ts:21 false <-- this.auth.currentUserAnonymously
auth.guard.ts:22 User is not staff
auth.service.ts:19 user signed in 

因为它在警卫之后从身份验证服务记录“用户登录”,这似乎意味着 auth.service 在警卫之后检查登录状态。我如何改变这个来先做服务?还是我需要打电话给警卫服务?谢谢

【问题讨论】:

  • 我不熟悉 AngularFireAuth 但你需要让 canActivate 返回 this.afAuth.auth.onAuthStateChanged 承诺
  • 阅读方法的定义 - 你可以返回一个 promise 或 observable,Angular 会在继续之前为你解析。
  • 我知道这一点,但我需要 2 个条件,因为可以匿名验证用户身份

标签: angular firebase firebase-authentication angularfire


【解决方案1】:

我认为您想在 canActivate 中使用 observable。你需要这样的东西:

canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    return this.afAuth.authState.map(auth => {
        if (isNullOrUndefined(auth)) {
            this.router.navigate(['/']);
            return false;
        } else {
            return true;
        }
    });
}

【讨论】:

    猜你喜欢
    • 2017-10-15
    • 2017-10-14
    • 2023-03-09
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 2017-11-03
    相关资源
    最近更新 更多