问题
I have an ionic 2 app that uses access tokens to authenticate to an API. If an access token expires, it can be exchanged for a new access token using a refresh token.
There is a function handling an API call that returns a promise. If the API call initially succeeds, the promise resolves. If there is a 401 (Unauthorized) error returned, I want to make another API call that uses a refresh token to get a new access token. Then, the original API call should be tried again with the new access token and either resolve if the data is received or reject if there was an error.
I currently have the function working as I intend it to. However, this function is very hard to read. I was wondering how I can refactor this to make it smaller and more readable.
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);
}
});
});
});
});
}
回答1:
Why not check your token state before you call?
You can use angular2-jwt to check expire state of your token before you retry. Angular2-jwt
Add a function like these:
loggedIn(token) {
return tokenNotExpired(null,token);
}
Your get request should be like this
if(!this.loggedIn(token))
{
//reset refresh token
}
// your plain & simple get request
No need to retry.Thanks
来源:https://stackoverflow.com/questions/45291910/ionic-2-retrying-api-call-with-new-access-token-if-unauthorized