Last active
February 28, 2021 09:25
-
-
Save pankajparkar/69d308017d9b020f41ec63ccdb70436d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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