I've been working to construct an Interceptor that will:
- Intercept every request
- Add authentication tokens in local storage
- Do the request anyway
- Get back this request, log the result and if there is a 401/403:
- Call an entrypoint to refresh token
- At the reception, retry the request
- Check the result and log if valid or not
In this case, I must manage two types of retry (for token management):
- One for django
- One for pryv that is another solution and have differents tokens that must be added in the request
I have trouble managing two nexted next.handle() The second one is never fired and the request is not retried...
Here's my code :
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);
}
Here for example, the 'console.log(uuid + " : success get new token for URL : " + req.url);' log will never be shown and the retry request will never be sent. How to manage it ? I've tried sending another HttpRequest, but the interceptor is catching it...
Thanks !
question from:https://stackoverflow.com/questions/65849090/angular-interceptors-how-to-manage-retry-nested-next-handle