16

Firebase Auth를 사용하여 각도 2 경로의 AuthGuard를 만들려고합니다. 각도 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 값을 반환합니다.

이 문제를 해결하는 가장 좋은 방법은 무엇입니까?

는 편집 :

는 관측을 반환 AuthGuard을 변경.

로그인으로 리디렉션되지 않으므로 작동합니다.하지만 대상 AuthGuarded Component는 렌더링되지 않습니다.

내 app.routes와 관련이 있는지 확실하지 않습니다. 해당 부분의 코드는 다음과 같습니다.

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

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

안녕하세요! 당신은 plunkr을 만들 수 있습니까? –

+0

@ GuillaumeLeMière Firebase 인증이 포함되어 있기 때문에 꽤 어려울 것입니다 ... – cerealex

답변

11

.take (1)을 사용하여 관찰 가능 정보를 완성하여 구성 요소를 렌더링합니다. 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

Angular 2.0.0으로 업그레이드 한 후 더 이상 map()을 사용할 수 없습니다. Ts는 '속성'지도 '가'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에서 take, mapdo를 가져올 것을 잊지 마십시오.

+0

내 날을 저장했습니다. :) –