2017-07-25 40 views
0

我有一個使用訪問令牌對API進行身份驗證的離子2應用程序。如果訪問令牌到期,則可以使用刷新令牌交換新的訪問令牌。Ionic 2在未經授權的情況下使用新的訪問令牌重試API調用

有一個處理API調用的函數返回一個promise。如果API調用最初成功,則承諾解決。如果返回401(未授權)錯誤,我想進行另一個使用刷新令牌獲取新訪問令牌的API調用。然後,應該使用新的訪問令牌再次嘗試原始API調用,並且或者在接收數據時解析,或者在出現錯誤時拒絕。

我目前的功能正如我打算那樣工作。但是,這個功能很難閱讀。我想知道如何重構這個,使它更小,更具可讀性。

public readAtmospherePrefs() { 
return new Promise((resolve, reject) => { 

    this.storage.get('email').then((email) => { 

    this.storage.get('token').then((token) => { 

     let headers = new Headers(); 
     headers.append('Authorization', token); 
     headers.append('Content-Type', 'application/json'); 

     let options = new RequestOptions({ headers: headers, search: new URLSearchParams("email=" + email) }); 

     //Attempt to get data 
     this.http.get('api/users/preferences/atmosphere', options).subscribe(res => { 
      let data = res.json(); 

      resolve(data); 
      resolve(res.json()); 
     }, (err) => { 
      let error = err; 

      //Need to send email and refresh the token if unauthorized 
      if(err.status === 401){ 
      this.storage.get('refreshToken').then((refreshToken) => { 
       let body = { email: email, refreshToken: refreshToken} 
       let headers2 = new Headers(); 

       headers2.append('Content-Type', 'application/json'); 

       //get new access token using the refresh token 
       let options2 = new RequestOptions({ headers: headers2}); 
       this.http.post('api/users/token', body, options2) 
       .subscribe(res => { 
       let data = res.json(); 
       let newToken = data.token; 
       //set new access token in storage 
       this.storage.set('token', newToken).then((newToken) => { 
         let headers3 = new Headers(); 
         headers3.append('Authorization', newToken); 
         headers3.append('Content-Type', 'application/json'); 

         //retry call with new access token 
         let options = new RequestOptions({ headers: headers3, search: new URLSearchParams("email=" + email) }); 
         this.http.get('api/users/preferences/atmosphere', options).subscribe(res => { 
          let data = res.json(); 

          resolve(data); 
          resolve(res.json()); 
         }, 
         (err) => { 
         reject(err); 
         }); 
        }); 

        }, (err) => { 

       reject(err); 
       }); 

      }); 

      } 
      else{ 
       console.log(error); 
       reject(err); 
      } 

     }); 
    }); 

    }); 

}); 

    } 

回答

0

爲什麼不在致電之前檢查令牌狀態?

您可以使用angular2-jwt在重試之前檢查令牌的過期狀態。 Angular2-jwt

添加一個功能類似這樣:

loggedIn(token) { 
    return tokenNotExpired(null,token); 
} 

你的GET請求應該是這樣的

if(!this.loggedIn(token)) 
     { 
      //reset refresh token 
     } 
    // your plain & simple get request 

無需retry.Thanks

相關問題