0

我有一个 ionic 2 应用程序,它使用访问令牌对 API 进行身份验证。如果访问令牌过期,可以使用刷新令牌将其交换为新的访问令牌。

有一个函数处理返回承诺的 API 调用。如果 API 调用最初成功,则 Promise 会解析。如果返回 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);
          }

        });
    });

  });

});

  }
4

1 回答 1

-1

为什么不在你打电话之前检查你的令牌状态?

您可以在重试之前使用angular2-jwt检查令牌的过期状态。Angular2-jwt

添加如下函数:

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

您的获取请求应该是这样的

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

无需重试。谢谢

于 2017-11-15T09:16:00.483 回答