Mi servicio de autenticación funciona casi bien, pero el problema es que obtengo la información si el usuario está conectado o no desde una solicitud http asíncrona.
ActivationGuard.ts
import {Injectable} from '@angular/core'; import {Router, RouterStateSnapshot, ActivatedRouteSnapshot} from '@angular/router'; import {Observable} from 'rxjs/Observable'; import {UserAuthenticationService} from './UserAuthenticationService'; interface CanActivate { canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>|Promise<boolean>|boolean } @Injectable() export class ActivationGuard implements CanActivate { constructor(private router: Router, private userService: UserAuthenticationService) { } public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { if (this.userService.isUserAuthenticated == false) { this.router.navigate(['/']); return false; } return true; } }
UserAuthenticationService.ts
import {Injectable, OnInit} from '@angular/core'; import {Http} from '@angular/http'; @Injectable() export class UserAuthenticationService implements OnInit { isUserAuthenticated: boolean = false; username: string = 'admin'; constructor(private http: Http) {} ngOnInit(){ this.http.get(`http://localhost/api/auth/isLogged/${this.username}`) .subscribe(res => { this.isUserAuthenticated = res.json(); }, err => { console.error('An error occured.' + err); }); } }
Cada vez que recibo false
(no me permite ingresar a la aplicación incluso si estoy conectado).
Pero si cambio isUserAuthenticated: boolean = false;
línea del archivo UserAuthenticationService.ts
a true
- nunca me echa - isUserAuthenticated
siempre es verdadero.
¿Puede ser causado por la solicitud http y su naturaleza asíncrona? ¿O tal vez hay una mejor manera de lidiar con eso?
Esperando cualquier ayuda. Gracias.
Puede devolver no solo booleano sino también Observable o Promise en el método canActivate:
ActivationGuard.ts
import { Injectable } from '@angular/core'; import {Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router'; import {Observable} from "rxjs/Observable"; import {UserAuthenticationService} from './UserAuthenticationService'; @Injectable() export class ActivationGuard implements CanActivate { constructor(private router: Router, private userService: UserAuthenticationService) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { return this.userService.isUserAuthenticated .do(success => { if (!success) { this.router.navigate(['/']); } }); } }
También hagamos que isUserAuthenticated sea un observable, por lo que ActivationGuard se suscribirá en esta canalización:
UserAuthenticationService.ts
import {Injectable} from '@angular/core'; import {Http} from '@angular/http'; import {Observable} from "rxjs/Observable"; @Injectable() export class UserAuthenticationService { public isUserAuthenticated:Observable<boolean>; username: string = 'admin'; constructor(private http: Http) { this.isUserAuthenticated = this.http.get(`http://localhost/api/auth/isLogged/${this.username}`) .map(res => res.json()) .share(); } }