16

私はFirebase Authを使用してAngle 2ルートのAuthGuardを構築しようとしています。 Angular 2 AuthGuard + Firebase Auth

この

はAuthGuardサービスです:

import { Injectable }    from '@angular/core'; 
import { CanActivate, Router, 
     ActivatedRouteSnapshot, 
     RouterStateSnapshot } from '@angular/router'; 
import { AuthService }   from './auth.service'; 

@Injectable() 
export class AuthGuard implements CanActivate { 

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

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { 
    if (this.AuthService.loggedIn) { return true; } 

    this.router.navigate(['login']); 
    return false; 
    } 
} 

そして、これは、ユーザのがログインし、そのコンストラクタでプロパティ「LOGGEDIN」に結果をバインドするかどうかを確認するのAuthServiceです。

import { Injectable } from '@angular/core'; 
import { AngularFire } from 'angularfire2'; 
import { Router } from '@angular/router'; 

@Injectable() 
export class AuthService { 
loggedIn: boolean = false; 

    constructor(
    public af: AngularFire, 
    public router: Router) { 
     af.auth.subscribe(user => { 
      if(user){ 
       this.loggedIn = true; 
      } 
     }); 
    } 
} 

ここでの問題は明らかに非同期です。 AuthGuardのcanActivate()は、 'loggedIn'をtrueに変更するためにサブスクリプションがデータを受信しないため、常にfalse値を返します。

これを修正するにはどうすればよいですか?

EDIT:

は、観察を返すようにAuthGuardを変更しました。

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { 
    return this.af.auth.map((auth) => { 
     if (!auth) { 
      this.router.navigateByUrl('login'); 
      return false; 
     } 
     return true; 
    }); 
    } 

あなたはログインにリダイレクトされないため、動作します...しかし、ターゲットのAuthGuarded Componentはレンダリングされません。

私のapp.routesと関係があるかどうかわかりません。

const routes: Routes = [ 
    { path: '', component: MainComponent, canActivate: [AuthGuard] }, 
    ... 
]; 

export const routing = RouterModule.forRoot(routes); 
+0

こんにちは!あなたは落書きを作れますか? –

+0

@GuillaumeLeMière炎ベースの認証が含まれているので、それはかなり難しいでしょう... – cerealex

答えて

11

は、(1)成分をレンダリングするために観察用い.takeを完了します。これは、一部のコードです。 AngularFireの新しいバージョンの

import {Observable} from "rxjs/Observable"; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/take'; 

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { 
    return this.af.auth.map((auth) => { 
     if (!auth) { 
      this.router.navigateByUrl('login'); 
      return false; 
     } 
     return true; 
    }).take(1); 
    } 
+0

角度2.0.0にアップグレードしたようです。私はもはやmap()を使用できません。 Tsは 'Property 'map'が 'AngularFireAuth'型に存在しないと言っています。 – cerealex

+0

私はインポート 'rxjs/add/operator/map'を追加して 'rxjs/add/operator/take'をインポートして動作させる必要がありましたが、結局は動作します。ありがとう! – cerealex

+0

それはあなたのために働いてうれしい。私はRC5からのアップグレード後も同じ問題があったので、輸入品について言及しておきました。 – codedesignr

1

、あなたの代わりにauthStateを使用する必要があります。

@Injectable() 
export class AuthGuard implements CanActivate { 
    constructor(
    private afAuth: AngularFireAuth, 
    private router: Router 
) {} 

    canActivate(): Observable<boolean> { 
    return this.afAuth.authState 
     .take(1) 
     .map(authState => !!authState) 
     .do(auth => !auth ? this.router.navigate(['/login']) : true); 
    } 
} 

rxjs/add/operatorからtakemapdoをインポートすることを忘れないでください。

+0

あなたは私の日を保存しています:) –