I am implementing my interceptor with refresh token in Angular and ionic using import {Storage} from '@ionic/storage';
I've done the next on my constructor:
let getToken = storage.get('TOKEN');
let getTs = storage.get('ts');
let getTypeRegister = storage.get('typeRegister');
let getEmail = storage.get('email');
let getPass = storage.get('password');
Promise.all([getToken, getTs, getTypeRegister, getEmail, getPass]).then(results => {
this.token = results[0];
this.ts = results[1];
this.typeRegister = results[2];
this.email = results[3];
this.password = results[4];
})
And my interceptor is :
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let getTsObs = Observable.fromPromise(this.storage.get('TOKEN'));
const tokenObservable = getTsObs.map(token => {
return req = req.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
});
return tokenObservable.flatMap((req) => {
return next.handle(req)
.do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
// do stuff to the response here
}
}
, (err: any) => {
if (err instanceof HttpErrorResponse) {
if (req.url.search('/auth')) {
if (err.status === 401) {
let newRequest = req.clone({
setHeaders: {
Accept: `application/json`,
'Content-Type': `application/json`
}
});
next.handle(newRequest);
} else {
if (err.status === 403 || err.status === 401) {
if (this.typeRegister == "loginWithEmail") {
this._up.loginPhoneObs(this.email, this.password).flatMap(res => {
return Observable.fromPromise(this.storage.set('TOKEN', res))
}).subscribe(res2 => {
console.log(res2);
})
}
else {
this._ctp.cleanStorage();
let nav = this.app.getActiveNav();
nav.setRoot('Login');
}
}
}
}
}
}
)
})
}
If the error is by token expired I need to get another token(loginPhoneObs) to save on storage(its a promise) :
this._up.loginEmailObs(this.email, this.password).flatMap(res => {
return Observable.fromPromise(this.storage.set('TOKEN', res))
}).subscribe(res2 => {
console.log(res2);
console.log('BINGO');
})
Another solution that I tried is the next, changing error by catch :
.catch((res: any) => {
console.log("ERROR" + res.status + " " + res.error.error);
if (req.url.search('/auth')) {
let newRequest = req.clone({
setHeaders: {
Accept: `application/json`,
'Content-Type': `application/json`
}
});
next.handle(newRequest);
} else {
if ((res.status === 403) && res.error.error === 'ERR_INVALID_SIGNATURE_OR_CLAIM') {
return this._up.loginEmailObs(this.email, this.password).flatMap((data: any) => {
console.log("TOKEN FROM DATA" + data);
if (data == '') {
console.log("TOKEN VACION");
} else {
console.log("TOKEN NO VACION");
return Observable.throw(res);
}
alert(data);
let clonedRequestRepeat = req.clone({
setHeaders: {
Authorization: `Bearer ${data}`
}
});
return next.handle(clonedRequestRepeat).do(event => {
if (event instanceof HttpResponse) {
console.log("Event on Refresh token");
}
})
})
} else if (res.status === 400) {
console.log("ERROR 400");
return Observable.throw(res);
} else if (res.status === 401) {
console.log("ERROR 401");
return Observable.throw(res);
} else {
return Observable.throw(res);
}
}
})
})
In this case, with catch, I dont know where should I do the next:
Observable.fromPromise(this.storage.set('TOKEN', res))
Could someone explain me how can i achive that ?
I've read 2 post : Ionic 3 + HttpClientModule and token from storage
And the solution using localstorage, my first version is here :
https://github.com/jossephalvarez/ionic-angular-interceptor
Thank you in advance