我一直在努力建造一个能:
request
H 210H 111在接收时重试结果并进行日志记录(如果有效的话)。
在这种情况下,我必须管理两种类型的重试(用于令牌管理):
1 pryv是另一种解决方案,必须在request
中添加不同的令牌
我在管理两个相邻的next.handle()时遇到了问题,第二个从未被触发,并且请求没有被重试.
这是我的密码:
export class HttpInterceptorService implements HttpInterceptor {
constructor(private authService: AuthenticationService,
private pryvAccessesService: PryvAccessesService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const uuid = new Date().valueOf();
if (!req.url.includes('api/authentication/token/')) {
const authReq = this.addTokensRequest(req);
console.log(uuid + " : sending request with tokens : " + req.url);
return next.handle(authReq).pipe(
map(res => {console.log(uuid + ' : request succedeed ! ' + req.url); return res;}),
catchError(err => {
console.log(uuid + ' : request failed ! ' + req.url);
// Django invalid token
if (err.status === 401) {
console.log(uuid + " : sending django refresh request : " + req.url);
return this.authService.refresh().pipe(
map((res: any) => {
const authReqRefreshed = this.addTokensRequest(req);
console.log(uuid + " : sending refreshed request : " + req.url);
return next.handle(authReqRefreshed).pipe(
map(res => {console.log( uuid + ' : success refreshed request ! ' + req.url); return res;}),
catchError(err => {console.log(uuid + " failed refreshed request : " + req.url); return throwError(err);})
);
})
)
// Pryv invalid token
} else if(err.status === 400 && err.error['error'] == 'Invalid access token within Pryv usage') {
console.log(uuid + ' : bad pryv token : ' + req.url);
return this.getNewTokenForUrl(req).pipe(
map((res: string) => {
console.log(uuid + " : success get new token for URL : " + req.url);
const authReqNewPryv = this.addTokensRequest(req); // <= code goes up to here
return next.handle(authReqNewPryv).pipe(
map(res => {console.log(uuid + ' : success request with new pryv token ! ' + req.url); return res;}), // <= this is never triggered
catchError((err) => {console.log(uuid + " : error request with new pryv token : " + req.url); return throwError(err);}) // <= this also is never triggered
);
}), catchError((err) => {console.log(uuid + " fail get new pryv token : " + req.url); return throwError(err);})
);
// Unrelated error
} else {
console.log(uuid + " error not related to authentication : " + req.url); return throwError(err);
}
})
);
} else {
console.log(uuid + " authentication, passing thru " + req.url); return next.handle(req);
}
例如,在这里,'console.log(uuid +):success获取URL的新令牌:“+ req.url);‘日志永远不会显示,重试请求也不会被发送。如何处理呢?我试过发送另一个HttpRequest,但是拦截器正在捕捉它.
谢谢!
发布于 2021-01-22 09:08:09
您应该将此拦截器的响应拆分为多个拦截器,如下所示:
AppModule中的保护者令牌:
// Important: Order of Interceptors matters!
export const httpInterceptorProviders = [
{ provide: HTTP_INTERCEPTORS, useClass: RetryInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: AuthTokensManagementInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: TelemetryInterceptor, multi: true },
];
Auth令牌拦截器:
public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return of(req).pipe(
mergeMap(() => getAcessToken() /*and add it to local storage*/)
mergeMap((accessToken: string) => {
if (accessToken) {
req = req.clone({
headers: req.headers.set(AuthorizationHeader, `${accessToken}`)
})
}
return next.handle(req).pipe(
catchError((error: HttpErrorResponse) => {
if (error instanceof HttpErrorResponse) {
if (error.status === 401)
this.authTokensManager.invalidateAccessToken(error.url);
}
}
return throwError(error);
})
);
}));
}
重试拦截器:
public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return of(req).pipe(
mergeMap((req: HttpRequest<any>) => {
return next.handle(req).pipe(
// Will continue the pipe if a request attempt has succeeded without errors, or exceeded max retries.
retryWhen((errors: Observable<any>) => errors.pipe(
// Enable only 2 retries, +1 for the original request.
take(this.maxRetries + 1),
skipWhile(() => disableRetry),
mergeMap((err: HttpErrorResponse, i: number) => {
if (i >= this.maxRetries) {
return throwError(err);
}
const errorCode = err.status;
if (errorCode == 401) {
return of(err);
}
return throwError(err);
}),
))
)
})
);
}
https://stackoverflow.com/questions/65849090
复制