Я реализую свой перехватчик с токеном обновления в Angular и ionic, используя import {Storage} из '@ ionic / storage';
Я сделал следующее на своем конструкторе:
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];
})
И мой перехватчик:
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');
}
}
}
}
}
}
)
})
}
Если ошибка по токену истекла, мне нужно получить другой токен (loginPhoneObs), чтобы сэкономить на хранилище (это обещание):
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');
})
Другое решение, которое я попробовал, - это следующее, изменяющее ошибку по улову:
.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);
}
}
})
})
В этом случае с уловом я не знаю, где мне делать следующее:
Наблюдаемый.fromPromise (this.storage.set ('TOKEN', res))
Может кто-нибудь объяснить мне, как мне этого добиться?
Я прочитал 2 поста: Ionic 3 +HttpClientModule и токен из хранилища
Angular - JWT Refresh Token
И решение с использованием localalstorage, моя первая версия здесь:
https://github.com/jossephalvarez/ionic-angular-interceptor
Заранее спасибо