可以激活' authGuard'无法阅读'可观察的当前用户' AuthServer

时间:2016-06-26 07:19:45

标签: angular angular2-routing

我使用angular2 rc.3和@ angular / router":" 3.0.0-alpha.7

我的auth.server

export class AuthService {
  isLogged:boolean;
  constructor(private principal:PrincipalService){
  this.authenticated();
}
  authenticated() {
    this.principal.currentUser().subscribe(
      e=> {
        if (!!e && e.authenticated) {
          this.isLogged = true;
        }
        this.isLogged = false;
      },
    error=> {
      this.isLogged = false;
    }
    )
  }

AuthGuard:

constructor(private auth:AuthService )  {}
canActivate(next: ActivatedRouteSnapshot,state: RouterStateSnapshot): boolean{ 
   // here the **auth.isLogged** is undefined !! why?**
    if(this.auth.isLogged){
      return true;
    }
     else {
      window.location.href='/login';
      return false;
    }

我设置了路由器

{
      path: 'property',
      component: PropertyHomeComponent,
      canActivate: [AuthGuard]
    }

当我打开' / property'页面,AuthGuard无法读取" this.auth.isLogged" ,并且没有重定向到' / login'页面,

如何解决?

2 个答案:

答案 0 :(得分:2)

我找到了革命。 (感谢@Michael的提示)

<强> AuthGuard

 return this.principal.currentUser().map(e=> {
      if (e) {
        return true;
      }
    }).catch(()=> {
      window.location.href = ConstantService.loginUrl;
      return Observable.of(false)
    })
  }

答案 1 :(得分:1)

在AuthGuard的isLogged方法试图访问它时,似乎没有设置canActivate。这是因为该变量的设置是异步的。

幸运的是,根据angular routing docs

  

因此,路由保护可以返回Observable<boolean>,路由器将等待观察者解析为truefalse

因此,在您的情况下,您可以将isLogged更改为observable,如下所示:

import { AsyncSubject } from 'rxjs/AsyncSubject';
export class AuthService {
  isLogged: AsyncSubject<boolean> = new AsyncSubject();
  constructor(private principal:PrincipalService){
  this.authenticated();
}
  authenticated() {
    this.principal.currentUser().subscribe(
      e=> {
        if (!!e && e.authenticated) {
          this.isLogged.next(true);
        } else {
          this.isLogged.next(false);
        }
        this.isLogged.complete();
      },
      error=> {
        this.isLogged.next(false);
        this.isLogged.complete();
      }
    )
  }

然后您需要更改AuthGuard的canActivate以返回可观察的内容:

canActivate(next: ActivatedRouteSnapshot,state: RouterStateSnapshot): boolean {
  return this.auth.isLogged
    .do(
      isLoggedIn => { if(!isLoggedIn) this.router.navigate(['/login']) },
      error => console.error(error)
    );

isLogged的值将以Observable<boolean>的形式返回。如果observable解析为dofalse方法将导航到/ login页面。

如果有效,请告诉我。我对rxjs(Observables)和路由器不太熟悉。