2017-04-15 44 views
1

我竭力要实现打字稿& RxJs一个函数,返回观察数据的从后端。我需要根据用户角色查询不同的端点。我正在使用angular-JWT进行身份验证。我有两个问题:查询不同的端点

  1. 目前代码编译很好,但第二对请求不断取消。为什么?

  2. 有没有比zip + throw + catch更好的方法呢?我一直在搜索rxjs文档,但什么都没发现。

代码:

public getData(): Observable<Data> { 
    return Observable.zip(
    this.userService.getCurrentUser(), 
    this.authHttp.get(this.adminUrl), 
    (user, adminResponse) => { 
     if (user.role == 'admin') { 
     return adminResponse.json() as BackendResponse 
     } else { 
     throw "You are not an admin"; 
     } 
    }) 
    .catch(error => { 
     return Observable.zip(
     this.userService.getCurrentUser(), 
     this.authHttp.get(this.normalUrl), 
     (user, normalResponse) => { 
      if (user.role == 'normal') { 
      return normalResponse.json() as BackendResponse 
      } else { 
      throw "You are not allowed to get this resource"; 
      } 
     }) 
    }) 
    .catch(error => { 
     return Observable.throw(error) 
    }); 
} 

管理端点返回两个管理员和普通用户(需要在我的项目)的一些数据,但如果他们询问他们的特殊的API标准的用户可以得到更多的数据。

+0

服务器应该拒绝任何未经授权的请求。 –

回答

0

这样的事情将起作用。我们有一个第一个可观察用户$,它返回关于用户的数据,而用户标志是admin。第二个可观察的auth $使用此信息创建一个请求,其中包含正确的路径和zip,它从两个可观察数据中获取数据并将其合并。

const user$ = Observable.of({name:'julia', isAdmin}) 
    .publishLast() 
    .refCount(); 

const auth$ = user$ 
.switchMap(user => 
    Observable.of(`${this.baseurl}${user.isAdmin ? 'adminPath' 
               :'normalpath'}`)); 

Observable.zip(user$, auth$, 
    (x,y) => `user is ${JSON.stringify(x)} and auth is ${y}`) 
    .subscribe(result => this.result = result); 
} 
0

检查用户是否处于正确角色,如果不是,则抛出客户端异常肯定是错误的。如果你的服务器允许访问成功,那么你有一个严重的安全漏洞。如果您的服务器正确阻止了访问,那么比您的所有检查都混乱无味。另外,捕获和重新抛出这样的异常是完全没有意义的,并导致冗余和复杂的代码。只是让错误表面。

鉴于这种情况,你应该需要的是像

export default class { 
    constructor(readonly authHttp: AuthHttp) { } 

    get urls() { 
    return { 
     admin: this.adminUrl, 
     normal: this.normalUrl 
    }; 
    } 

    getData(): Observable<BackendResponse> { 
    return this.userService.getCurrentUser() 
     .flatMap(user => this.authHttp.get(this.urls[user.role])) 
     .map(response => response.json() as BackendResponse); 
    } 
}