2016-07-17 191 views
23

我想使用Angular2路由器衛兵來限制對我的應用程序中的某些頁面的訪問。我正在使用Firebase身份驗證。爲了檢查用戶是否使用Firebase登錄,我必須使用回調呼叫FirebaseAuth對象上的.subscribe()。這是在保護的代碼:Angular2 canActivate()調用異步函數

import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; 
import { AngularFireAuth } from "angularfire2/angularfire2"; 
import { Injectable } from "@angular/core"; 
import { Observable } from "rxjs/Rx"; 

@Injectable() 
export class AuthGuard implements CanActivate { 

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

    canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<boolean>|boolean { 
     this.auth.subscribe((auth) => { 
      if (auth) { 
       console.log('authenticated'); 
       return true; 
      } 
      console.log('not authenticated'); 
      this.router.navigateByUrl('/login'); 
      return false; 
     }); 
    } 
} 

當導航到具有防護件在其上,或者authenticated,或not authenticated一個頁被打印到控制檯(一些延遲等待來自火力的響應之後)。但是,導航從未完成。另外,如果我沒有登錄,我將重定向到/login路線。所以,我遇到的問題是return true不會向用戶顯示請求的頁面。我假設這是因爲我正在使用回調,但我無法弄清楚如何去做。有什麼想法嗎?

+0

import像這樣 - > import {Observable} from'rxjs/Observable'; –

回答

50

canActivate需要返回一個Observable是完成:

@Injectable() 
export class AuthGuard implements CanActivate { 

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

    canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<boolean>|boolean { 
     return this.auth.map((auth) => { 
      if (auth) { 
       console.log('authenticated'); 
       return true; 
      } 
      console.log('not authenticated'); 
      this.router.navigateByUrl('/login'); 
      return false; 
     }).first(); // this might not be necessary - ensure `first` is imported if you use it 
    } 
} 

有一個return失蹤,我用map()代替subscribe()因爲subscribe()返回Subscription不是Observable

+0

你能展示如何在其他組件中使用這個類嗎? –

+0

不確定你的意思。你用這個和路由,而不是組件。請參閱https://angular.io/docs/ts/latest/guide/router.html#!#guards –

+0

Observable不會在我的情況下運行。我沒有看到任何控制檯輸出。但是,如果我有條件地返回布爾值(如文檔中所示),控制檯會被記錄下來。這個.auth是一個簡單的Observable嗎? – cortopy

5

canActivate可以返回Promise那還解決了boolean

1

您可以使用Observable來處理異步邏輯部分。這裏是我測試的代碼,例如:

import { Injectable } from '@angular/core'; 
import { CanActivate } from '@angular/router'; 
import { Observable } from 'rxjs/Observable'; 
import { DetailService } from './detail.service'; 

@Injectable() 
export class DetailGuard implements CanActivate { 

    constructor(
    private detailService: DetailService 
) {} 

    public canActivate(): boolean|Observable<boolean> { 
    if (this.detailService.tempData) { 
     return true; 
    } else { 
     console.log('loading...'); 
     return new Observable<boolean>((observer) => { 
     setTimeout(() => { 
      console.log('done!'); 
      this.detailService.tempData = [1, 2, 3]; 
      observer.next(true); 
      observer.complete(); 
     }, 1000 * 5); 
     }); 
    } 
    } 
}