首页 文章

canActivate in 'authGuard'可以't read ' observable当前用户'的AuthServer

提问于
浏览
4

我使用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" ,并且没有't redirect to the ' / login'页面,

怎么解决?

2 回答

  • 2

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

    AuthGuard

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

    在AuthGuard的 canActivate 方法试图访问它时,看起来没有设置 isLogged . 这是因为该变量的设置是异步的 .

    幸运的是,根据angular routing docs

    因此,路由保护可以返回Observable <boolean>,路由器将等待observable解析为true或false .

    因此,在您的情况下,您可以将 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解析为 falsedo 方法将导航到/ login页面 .

    让我知道这个是否奏效 . 我对rxjs(Observables)和路由器不太熟悉 .

相关问题