У меня есть служба, которая отправляет запросы на отдых моим веб-службам, и я хочу, чтобы, если я уловил ошибку аутентификации, я попытался снова войти в систему с помощью маркера обновления, а затем перезапустил исходный запрос и вернулновый результат.
У меня есть, например, функция get:
protected get<T>(path: string, params: any, mapper: Function): Observable<T> {
const httpParams: HttpParams = new HttpParams({ fromObject: params});
let urlParams = httpParams.toString();
if (urlParams) {
urlParams = urlParams.replace(/%5B%5D/g, '[]');
}
let get = this._http.get<T>((path.indexOf('data') === 0 ? '' : this._webservicesUrl)
+ this.mapParameters(path, params) + '?' + urlParams, {
headers: this.headers,
responseType: 'json',
withCredentials: true,
observe: 'response'
});
return get.pipe(
tap((res) => console.log('HTTP GET - ' + path)),
map((response: HttpResponse<T>) => mapper(response.body)),
catchError(this.authError(path, params, mapper)),
);
}
На данный момент я не набрал this.authError
(он пуст, потому что я не знаю, как поступить).
Мне просто нужно указать, что нужно сделать для передачи моего authError, и если это ошибка аутентификации (код 401 для меня), тогда ответ на карте должен быть изменен новым ответом на запрос.
Я также пытался с перехватчиком, но я не могу изменить ответ, просто запросите новую аутентификацию и перезапустите запрос.
- РЕДАКТИРОВАТЬ -
Я думаю, что есть какое-то отношение к перехватчикам, я запускаю что-то, что все еще не работает, но это хорошая отправная точка.
Вот перехватчик, который я создал:
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpRequest, HttpClient, HttpInterceptor } from '@angular/common/http';
import { Observable, throwError } from 'rxjs/index';
import { catchError, switchMap } from "rxjs/internal/operators";
import { AuthenticationService } from "../services/rest/authentication.service";
import { AppStateService } from "../services/app-state.service";
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(public http: HttpClient, public auth: AuthenticationService, private appState: AppStateService) {
}
public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('===== Intercept =====');
console.log(req);
return next.handle(req).pipe(
catchError(err => {
console.log(err);
this.refreshToken().subscribe( resolve => {
console.log('RESOLVE');
// clone the original request
if (resolve) {
console.log('REQ REPEAT');
const authReqRepeat = req.clone({
headers: req.headers.set('Authorization', 'Bearer' + this.appState.token)
});
// resend the request
return next.handle(authReqRepeat);
}
}, error => {
console.log('ERROR');
return throwError(error);
});
})
);
}
public refreshToken(): Observable<boolean> {
const obs: Observable<boolean> = new Observable<boolean>(observer => {
this.auth.loginWithEmail(this.appState.userMail, null, 'refresh_token', this.appState.refreshToken).subscribe(
resolve => {
console.log('RELOG OK');
console.log(this.appState);
observer.next(true);
observer.complete();
}, error => {
console.log('RELOG NOT OK');
observer.next(false);
observer.complete();
}
);
});
return obs;
}
}
Кажется,работает отлично, хожуt весь мой console.log, но когда дело доходит до return next.handle(authReqRepeat);
, запрос не отправляется, поэтому приложение все еще ожидает ответа, который никогда не будет получен.