Angular2需要异步get的结果才允许访问路由

时间:2016-07-14 12:11:01

标签: http angular angular-routing

我正在使用AuthGuard保护我的路线,确保用户在看到该应用的信息中心之前已正确登录。

AuthGuard:

canActivate(
    next:  ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ) {
    // return true;
    return this.userService.getValidLoginCheck();
}

但是getValidLoginCheck()不返回布尔值:

getValidLoginCheck(): boolean {
    let headers = new Headers();

    let options = new RequestOptions({ headers: headers });

    headers.append('authorization', this.getToken());

    this.http.get(this.baseUrl + 'api/auth/checkToken', options)
      .map(res => res.json())
      .subscribe(data => {return data.message === 'valid token' });

  }

我知道为什么会发生这种情况,但是如何让getValid ...函数等待http.get完成,这样我才能正确地保护我的路线?

2 个答案:

答案 0 :(得分:2)

CanActivate方法接受3种类型的响应(Observable,Promise和boolean),这是方法的签名:

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

因此,您可以利用Observable响应并将Service的Observable转换为Observable,如下所示:

canActivate(
    next:  ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ) {

       return new Observable<boolean>((observer: Observer<boolean>) => {
         this.userService.getValidLoginCheck()
         .subscribe(data => {observer.next(data.message === 'valid token')},
          error => { console.log("error while calling getValidLoginCheck" ); observer.next(false)});
         observer.complete();
       });
}

你应该从你的服务中返回一个observable:

getValidLoginCheck(): Observable<Response> {
    let headers = new Headers();

    let options = new RequestOptions({ headers: headers });

    headers.append('authorization', this.getToken());

    return this.http.get(this.baseUrl + 'api/auth/checkToken', options)
      .map(res => res.json());
  }

这就是我所做的,它对我有用,我更喜欢在subscribe中调用一个方法并发送观察者和http响应然后评估隔离方法中的响应,但这是我个人的偏好,我希望它帮助

答案 1 :(得分:1)

您可以通过可以激活的返回observable来实现此目的

allowed: Observable<boolean>
getValidLoginCheck(): boolean | Observable<boolean> {
    let headers = new Headers();

    let options = new RequestOptions({ headers: headers });

    headers.append('authorization', this.getToken());
//save URL from routerStateSnapshot from canActivate like URL = state.url
    this.http.get(this.baseUrl + 'api/auth/checkToken', options)
      .map(res => res.json())
      .subscribe(data =>  { this.allowed = Observable.of(true);

this.router.navigateByUrl(URL);     return data.message ==='valid token'},err =&gt; {this.allowed = Observable.of(true);})     返回this.allowed;