I'm using Angular / Typescript. The application communicates with an API, an access_token is stored in storage.
On every request the interceptor checks if the access_token is still valid.
When the access_token is expired, the application needs to refresh the access_token with the refresh_token and continue with the last request (with the new access_token)
The problem
I cannot get to clone the original request (with the expired token) and execute it.
The call to request the new access_token is interfering with the interceptor.
What is the best way to:
- Request the new token.
- Set the new token.
- Resume the call that had the expired token and clone to run successful?
The interceptor:
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// add authorization header with jwt token if available
if (!this.isRefreshing) {
if (this.authenticationService.checkLoginState()) {
// Check if access_token is valid.
this.currentUser = JSON.parse(localStorage.getItem('auth'));
if (new Date(this.currentUser.access_token_expires) > new Date()) {
// Access token is valid, clone request and continue.
request = request.clone({
setHeaders: {
Authorization: `Bearer ${this.currentUser.access_token}`
}
});
return next.handle(request);
} else {
// Token is not valid, request new token with reLogin().
this.reLogin().then(any => {
// New token has been set, now run old request with new token.
return next.handle(request);
}, error => {
this.authenticationService.logout();
});
}
}
} else {
return next.handle(request);
}
}
reLogin:
reLogin() {
return new Promise(function (resolve, reject) {
this.isRefreshing = true;
// Check if refresh token is valid
if (new Date(this.currentUser.refresh_token_expires) > new Date()) {
this.authenticationService.loginWithRefreshToken(this.currentUser.refresh_token).subscribe(data => {
// Using refresh_token was successful
this.currentUser = JSON.parse(localStorage.getItem('auth'));
this.isRefreshing = false;
resolve();
}, error => {
console.error(error);
reject();
});
});
}
( if (!this.isRefreshing) )this value is set to true when requesting the new token. - Wouter DoornbosTypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.- Wouter Doornbos