Skip to content

Instantly share code, notes, and snippets.

@pankajparkar
Last active February 28, 2021 09:25
Show Gist options
  • Save pankajparkar/69d308017d9b020f41ec63ccdb70436d to your computer and use it in GitHub Desktop.
Save pankajparkar/69d308017d9b020f41ec63ccdb70436d to your computer and use it in GitHub Desktop.
import { AuthService } from './auth.service';
import { Injectable } from '@angular/core';
import {
HttpRequest, HttpHandler, HttpInterceptor, HttpSentEvent,
HttpHeaderResponse, HttpProgressEvent, HttpResponse, HttpUserEvent
} from '@angular/common/http';
import { Observable, BehaviorSubject, throwError} from 'rxjs';
import { catchError, switchMap, finalize, filter, take, map } from 'rxjs/operators';
import { Router } from '@angular/router';
import { JwtHelperService } from '@auth0/angular-jwt';
const helper = new JwtHelperService();
// You can add URL which don't need AUTH header
const whiteListUrls = ['login', 'refreshToken'];
@Injectable()
export class CustomHttpInterceptorService implements HttpInterceptor {
constructor(
private auth: AuthService,
private router: Router) {}
// Check expiry of token, first decode token
// extract data, and verify expiry timing wrt currentTime
// should be less that currentTime
private isTokenExpired(token): boolean {
const decoded = token && helper.decodeToken(token);
const date = new Date().getTime();
return decoded && new Date(decoded.exp * 1000).getTime() <= date;
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent |
HttpResponse<any> | HttpUserEvent<any> | any> {
const token = localStorage.get('access_token');
const refresh_token = localStorage.get('access_token');
const isExpired = this.isTokenExpired(token);
// Directly allowed whitelisted URL's
if (whiteListUrls.find(w => request.url.includes(w)) || !isExpired) {
return next.handle(request);
}
// If accessToken is expired
if (isExpired) {
// Retreive new refresh_token
const refreshToken = this.auth.refreshToken(refresh_token).pipe(
// Applying catchError only to refreshToken call
catchError(_ => {
// Logout if refresh call fails
return this.logout() as any;
}),
switchMap((user: any) => {
// when new user token retrieved
if (user) {
// Update token locally
this.auth.updateTokens(user);
// Make the ajax call after by passing `accessToken`
return next.handle(this.addTokenToRequest(request, user.accessToken));
}
// Log out if there is no user
return this.logout() as any;
})
);
return refreshToken as any;
} else {
// Make normal ajax call just by passing token
return next.handle(this.addTokenToRequest(request, token));
}
}
private addTokenToRequest(request: HttpRequest<any>, token: string): HttpRequest<any> {
// Token appended in the request header.
return request.clone({ setHeaders: { Authorization: `Bearer ${token}`}});
}
private logout() {
this.auth.logout();
this.router.navigate(['login']);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment