2017-04-15 41 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); 
    } 
}