2017-10-17 150 views
2

我在使用Firebase時遇到了Angular 4應用程序和canActivate警衛的問題。Angular4 canActivate和google firebase

我有這個服務的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爲c在守衛後注意登錄狀態。我如何改變這個做服務?或者我需要撥打警衛的服務電話嗎?謝謝

+1

我不熟悉AngularFireAuth,但你需要有canActivate返回this.afAuth.auth.onAuthStateChanged諾 – Carsten

+0

閱讀方法的定義 - 你可以返回承諾或可觀察,Angular將在繼續之前爲您解決。 – jonrsharpe

+0

我知道這一點,但我需要2個條件,因爲用戶可以匿名進行身份驗證 –

回答

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