Created
March 12, 2019 16:09
-
-
Save bioyeneye/75eccb4e247457b326fe06d53f811ad6 to your computer and use it in GitHub Desktop.
ionic 3 interceptor
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 {Observable, BehaviorSubject} from 'rxjs'; | |
import {_throw} from "rxjs/observable/throw"; | |
import {take, filter, catchError, switchMap, finalize} from 'rxjs/operators'; | |
import {Injectable, Injector} from "@angular/core"; | |
import {HttpInterceptor, HttpRequest, HttpHandler, HttpSentEvent, HttpHeaderResponse, HttpProgressEvent, | |
HttpResponse, HttpUserEvent, HttpErrorResponse} from "@angular/common/http"; | |
import {ResetApiProvider} from "../providers/reset-api/reset-api"; | |
import {Events} from "ionic-angular"; | |
@Injectable() | |
export class AuthInterceptor implements HttpInterceptor { | |
isRefreshingToken: boolean = false; | |
tokenSubject: BehaviorSubject<string> = new BehaviorSubject<string>(null); | |
constructor(private injector: Injector, public event: Events) {} | |
addToken(req: HttpRequest<any>, token: string): HttpRequest<any> { | |
return req.clone({setHeaders: {Authorization: 'Bearer ' + token}}) | |
} | |
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> { | |
const authService = this.injector.get(ResetApiProvider); | |
return next.handle(this.addToken(req, authService.getAuthToken())).pipe( | |
catchError(error => { | |
if (error instanceof HttpErrorResponse) { | |
switch ((<HttpErrorResponse>error).status) { | |
case 400: | |
return this.handle400Error(error); | |
case 401: | |
return this.handle401Error(req, next); | |
default: | |
return _throw(error); | |
} | |
} else { | |
return _throw(error); | |
} | |
})); | |
} | |
//maybe use later for blacklist tokens | |
handle400Error(error) { | |
if (error && error.status === 400 && error.error && error.error.error === 'invalid_grant') { | |
// If we get a 400 and the error message is 'invalid_grant', the token is no longer valid so logout. | |
return this.logoutUser(); | |
} | |
return _throw(error); | |
} | |
handle401Error(req: HttpRequest<any>, next: HttpHandler) { | |
if (!this.isRefreshingToken) { | |
this.isRefreshingToken = true; | |
// Reset here so that the following requests wait until the token | |
// comes back from the refreshToken call. | |
this.tokenSubject.next(null); | |
const authService = this.injector.get(ResetApiProvider); | |
return authService.refreshToken().pipe( | |
switchMap((newToken: string) => { | |
console.log('bbbbbbb'); | |
if (newToken) { | |
this.tokenSubject.next(newToken); | |
return next.handle(this.addToken(req, newToken)); | |
} | |
console.log('qqqq'); | |
// If we don't get a new token, we are in trouble so logout. | |
return this.logoutUser(); | |
}), | |
catchError(error => { | |
// If there is an exception calling 'refreshToken', bad news so logout. | |
return this.logoutUser(); | |
}), | |
finalize(() => { | |
this.isRefreshingToken = false; | |
}),); | |
} else { | |
return this.tokenSubject.pipe( | |
filter(token => token != null), | |
take(1), | |
switchMap(token => { | |
return next.handle(this.addToken(req, token)); | |
}),); | |
} | |
} | |
logoutUser() { | |
const authService = this.injector.get(ResetApiProvider); | |
authService.logout(); | |
this.event.publish('UNAUTHORIZED'); | |
return _throw("please login"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment