3

Ich versuche einen Router Guard in Angular.js 2 (2.0.0-rc.4) (erstellt von angular cli) zu schreiben, der AngularFire (2.0. 0-beta.2), um den Anmeldestatus zu überprüfen und den Benutzer (anonym) anzumelden, wenn der Benutzer bereits angemeldet ist, bevor er in den Status zugelassen wird.Einen Route Guard schreiben, um auf Auth in AngularFire und Angularjs 2 zu warten

Mein Wächter-Code ist:

canActivate() { 
    /* This part is to detect auth changes and log user in anonymously */ 
    this.auth 
     .subscribe(auth => { 
     if (!auth) { 
      this.auth.login(); 
     } 
     }); 

    /* This part is to listen to auth changes and IF there is an auth, resolves this guard with a true to let user in */ 
    return this.auth 
     .asObservable() 
     .filter(auth => { 
     return auth ? true : false; 
     }) 
     .map(x => { 
     console.log("TEST 1000"); 
     return true; 
     }); 
} 

Wenn ich die Anwendung ausführen, obwohl ich TEST 1000 Konsolenausgabe angezeigt, dass canActivate() Zurückgeben eine true meine Route nicht aktiviert ist.

Ich frage mich, ob es in meiner Logik fehlerhafte Denkweise gibt, oder gibt es irgendwelche guten Ideen, um dies intelligent zu debuggen.

Antwort

3

Ich bin derzeit dies für Auth zu überprüfen verwenden und wenn der Benutzer admin:

Auth Service:

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

import { Router } from '@angular/router'; 

import { AngularFire } from 'angularfire2'; 


import { Observable } from 'rxjs/Observable'; 

import { Subject } from 'rxjs/Rx'; 


@Injectable() 

export class AuthService { 


  admin$: Subject<boolean>; 


  private user: any = null; 


  constructor(private af: AngularFire, private router: Router) { 

    this.admin$ = <Subject<boolean>>new Subject(); 

    this.af.auth.subscribe(

      auth => { 

        if(auth){ 

          this.user = af.database.object(`users_list/${auth.uid}`).subscribe(

            res => { 

              this.user = res; 

              this.admin$.next(this.user.role === 10); 

              this.admin$.complete(); 

            }, 

            err => this.admin$.error(err) 

          ); 

        }else{ 

          this.router.navigate(['auth']); 

          this.admin$.next(false); 

          this.admin$.complete(); 

        } 

      } 

    ); 

  } 


  doLogin(credentials){ 

    this.admin$ = <Subject<boolean>>new Subject(); 

    this.af.auth.login(credentials); 

  } 


  admin() { 

    return this.admin$; 

  } 

} 

Auth Schutzdienst:

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


  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean { 


    this.authService.admin().subscribe(

      res => { 

        // Navigate to the login page 

        if(!res) { 

          this.router.navigate(['/auth']); 

        } 

      }, 

      err => console.log(err), 

      () => { 

        // console.log('auth guard can activate complete') 

      } 

    ); 


    return this.authService.admin(); 

  } 

Nun, wie dies bezieht sich zu Ihrer Frage ist, dass ohne complete() auf admin$, wird es nicht funktionieren. Die Konsole protokolliert true, aber der Router navigiert nicht zum nächsten Status.

Ich bin ziemlich immer noch die Observablen hängen (daher schlechte Implementierung), und wenn Sie Ihren Code beheben würde, würde ich wirklich gerne das Endergebnis sehen, weil es so viel sauberer aussieht und wahrscheinlich ist besserer Weg, es zu tun. Prost!

+0

Sie haben Recht! Mein Problem war in der Tat, es war nicht vollständig. Ich habe '.asObservable()' mit 'take (1)' geändert, um nur einen Wert zu erwarten und ihn danach zu vervollständigen, und es hat angefangen zu arbeiten! –

2

Können Sie testen, ob dies Ihr Problem

canActivate() { 

    this.auth 
     .subscribe(auth => { 
      if (!auth) this.auth.login() 
     }); 
    let authObs = this.auth 
     .asObservable() 
     .filter(auth => auth ? true : false) 
     .map(x => { 
      console.log("TEST 1000"); 
      return true; 
     }); 

    authObs.subscribe(a => return true); 

löst ich glaube, das Problem ist, dass Sie nur die beobachtbaren erstellen und eigentlich nicht abonnieren. CanActivate erwartet ein Versprechen oder bool nicht ein Observable.

+0

Hallo Filip, ich versuchte dies, aber leider 'canActivate()' erwartet Typ von 'Observable ' oder 'boolean', so dass Ihr nicht kompiliert wurde. 'Exportschnittstelle CanActivate { canActivate (Route: ActivatedRouteSnapshot, Status: RouterStateSnapshot): Observable | Boolesch; } 'ist die Schnittstelle davon, entsprechend der Standardeinstellung von CLI, in der Hoffnung, dass es auf dem neuesten Stand ist. –

+0

Ich bezog mich auf die Dokumentation auf angular.io. Export CanActivate (Optionen: CanActivateAnnotation): (hook: (nächstes: ComponentInstruction, prev: ComponentInstruction) => Versprechen | boolean). Du bist vielleicht der Letzte, den ich wirklich nicht kenne. –