I was wondering if anybody has an example of how to refresh the token and retry HTTP calls using the http interceptor and angular2-jwt v1.0 for angular4+.
Thanks
Here's my interceptor:
import { AuthToken } from '../../account/dto/auth-token';
import { AuthTokenRepository } from '../../account/repositories/auth-token.repository';
import { Injectable } from '@angular/core';
import {
HttpClient,
HttpErrorResponse,
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpResponse
} from '@angular/common/http';
import { Injector } from '@angular/core';
import { JwtHelper } from 'angular2-jwt';
import { Observable } from 'rxjs/Observable';
import { Router } from '@angular/router';
import { SlimLoadingBarService } from 'ng2-slim-loading-bar';
import { SocketService } from './socket.service';
import { Subscription } from 'rxjs/Subscription';
import { environment } from '../../../environments/environment';
import { global } from '../static/global';
import 'rxjs/add/operator/do';
@Injectable()
export class InterceptorService implements HttpInterceptor {
private isUpdating = false;
private jwtHelper: JwtHelper = new JwtHelper();
private offsetSeconds = 3600;
private subscriptions = new Array<Subscription>();
constructor(
private injector: Injector,
private router: Router,
private slimLoadingBarService: SlimLoadingBarService,
private socketService: SocketService
) {}
public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.slimLoadingBarService.start();
const token = localStorage.getItem(global.tokenName);
if (request.url.startsWith(environment.baseUrl)) {
request = request.clone({
setHeaders: {
Authorization: token != null ? token : '',
'Content-Type': 'application/json'
}
});
}
return next.handle(request).do(
(event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
this.slimLoadingBarService.complete();
if (!request.url.includes('auth-tokens')) { // my api endpoint to avoid to trigger the interceptor when I refresh the token.
try {
const expirationLeft = this.jwtHelper.getTokenExpirationDate(token).getTime() - Date.now();
if (expirationLeft > 0 ) {
if (expirationLeft < (this.offsetSeconds * 1000) && !this.isUpdating) {
this.updateAuthToken();
}
}
} catch (e) {}
}
}
},
(error: any) => {
this.slimLoadingBarService.complete();
if (error instanceof HttpErrorResponse) {
if (error.status === 401) {
localStorage.clear();
this.socketService.close();
for (const sub of this.subscriptions) {
sub.unsubscribe();
}
this.router.navigateByUrl('/sign-in');
}
}
}
);
}
/**
* Updates the token if it will expire and the current user is navigating.
*/
private updateAuthToken(): void {
this.isUpdating = true;
const authTokenRepository = this.injector.get(AuthTokenRepository);
this.subscriptions.push(authTokenRepository.getAuthTokenUpdate().subscribe(
(authToken: AuthToken) => {
localStorage.setItem(global.tokenName, authToken.value);
this.isUpdating = false;
}
));
}
}
See #18224
@rsaenen Thank you. Can you post your code for AuthTokenRepository? Specifically what does this line do const authTokenRepository = this.injector.get(AuthTokenRepository);?
Thanks again
@n0490b It just gets the AuthTokenRepository class, which is then used here: authTokenRepository.getAuthTokenUpdate()
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you have not received a response for our team (apologies for the delay) and this is still a blocker, please reply with additional information or just a ping. Thank you for your contribution! 🙇♂️
Most helpful comment
Here's my interceptor:
See #18224