我有一项服务可以对我的Web服务发出一些其他请求,而我想做的是,如果遇到身份验证错误,我尝试使用刷新令牌重新登录用户,然后重新启动原始请求并返回新结果。
例如,我有一个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;
}
}
似乎一切正常,我已收到所有console.log文件,但是当涉及到return next.handle(authReqRepeat);
时,请求未发送,因此应用程序仍在等待永远不会出现的答案。