2016-06-18 13 views
8

czytałem instrukcji tutaj: https://angular.io/docs/ts/latest/guide/router.htmlAuthGuard nie czekać do uwierzytelniania, aby zakończyć przed sprawdzeniem użytkownik

wydaje się dość prosta, jednak nie jestem pewien, w jaki sposób korzystać z uwierzytelniania angularfire2 w ramach straży auth (canActivate). Co Próbowałem to:

AuthService

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

@Injectable() 
export class AuthService { 

    private user: any; 

    constructor(private af: AngularFire) { 
    this.af.auth.subscribe(user => { 
     this.user = user; 
    }) 
    } 

    get authenticated(): boolean { 
    return this.user ? true : false; 
    } 

} 

AuthGuard

@Injectable() 
export class AuthGuard implements CanActivate { 

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

    canActivate(): Observable<boolean> | boolean { 
    if (this.authService.authenticated) 
     return true; 

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

} 

Dodałem także AuthService bootstrap dostawców. Ten sposób działa dobrze, jednak moim głównym problemem jest to, że odświeżam (lub początkowo ładuję) stronę, która ma AuthGuard, zawsze przekierowuje mnie do strony logowania, ponieważ AuthGuard nie czeka na odpowiedź uwierzytelnienia. Czy istnieje sposób oczekiwania na zakończenie uwierzytelniania (nawet jeśli się nie udało) i następnie sprawdzić, czy użytkownik jest uwierzytelniony?

+0

Zobacz tę odpowiedź, że wdrożył straży auth prawidłowo http://stackoverflow.com/a/37889258/652850 –

+0

naprawdę nie rozwiązać mój problem z angularfire2. – Andrew

Odpowiedz

11

Problem dotyczy kodu. W AuthGuard sprawdzasz wynik metody authenticated(), która najprawdopodobniej zwróci wartość false, ponieważ właściwość użytkownika nadal nie jest ustawiona. Spróbuj tego:

AuthService:

import { Injectable } from '@angular/core'; 
import { AngularFire } from 'angularfire2';'; 
import { Observable } from 'rxjs/Observable'; 

@Injectable() 
export class AuthService { 

    private user: any; 

    constructor(private af: AngularFire) { } 
    setUser(user) { this.user = user; } 
    getAuthenticated(): Observable<any> { return this.af.auth; } 
} 

AuthGuard:

@Injectable() 
export class AuthGuard implements CanActivate { 

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

    canActivate(): Observable<boolean> | boolean { 
    // here check if this is first time call. If not return 
    // simple boolean based on user object from authService 
    // otherwise: 

    return this.authService.getAuthenticated.map(user => { 
      this.authService.setUser(user); 
      return user ? true : false; 
    }) 

    } 
} 
+0

Dzięki! Czy istnieje sposób modyfikowania tego, aby uzyskać dane użytkownika w konstruktorze AuthService? Ze sposobem, w jaki to rozwiązałeś, nie otrzymuję danych użytkownika tylko na strzeżonych trasach, ale na przykład mam nagłówek, który będzie pokazywał adres e-mail użytkownika również na niestrzeżonych trasach. – Andrew

+0

Również to nie działa, ponieważ metoda 'canActivate()' musi zwrócić 'Observable | boolean', ale w twoim przykładzie nic nie zwraca. Jak mogę to rozwiązać? – Andrew

+0

Przepraszam, zapomniałem zwrócić wynik w canActivate. – Baumi

6

mogą być różne w niektórych wersjach routera ale musiałem wrócić zauważalny że uzupełnia .

import { CanActivate, Router } from '@angular/router' 

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

    canActivate(): Observable<boolean> { 
    return this.af.auth.map(user => { 
     if (user != null) 
     return true 
     this.router.navigate(['/login']) 
    }) 
    .take(1) // To make the observable complete after the first emission 
    } 
} 
Powiązane problemy