【问题标题】:Querying different endpoints查询不同的端点
【发布时间】:2017-09-11 17:54:51
【问题描述】:

我正在努力在 TypeScript 和 RxJs 中实现一个从后端返回 Observable 数据的函数。我需要根据用户角色查询不同的端点。我正在使用 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,他们可以获得更多数据。

【问题讨论】:

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

标签: angular rxjs user-roles


【解决方案1】:

检查用户是否处于正确的角色,如果不是,则抛出客户端异常绝对是错误的。如果您的服务器允许访问成功,那么您就有一个严重的安全漏洞。如果您的服务器正确阻止了访问,那么您的所有检查都是令人困惑且毫无意义的。

此外,像这样捕获和重新抛出异常是完全没有意义的,并且会导致冗余和复杂的代码。让错误浮出水面。

鉴于此,您只需要类似

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);
  }
}

【讨论】:

    【解决方案2】:

    类似的东西会起作用。我们有一个第一个可观察的 user$,它返回有关用户的数据,并且标志是 user is admin。第二个 observable auth$ 使用此信息创建具有正确路径和 zip 的请求,该请求从两个 observable 获取数据并将它们组合起来。

    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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-03
      • 1970-01-01
      • 1970-01-01
      • 2015-12-14
      • 2020-11-10
      • 2018-06-19
      • 1970-01-01
      相关资源
      最近更新 更多