Skip to content

Instantly share code, notes, and snippets.

@bioyeneye
Created March 12, 2019 16:09
Show Gist options
  • Save bioyeneye/75eccb4e247457b326fe06d53f811ad6 to your computer and use it in GitHub Desktop.
Save bioyeneye/75eccb4e247457b326fe06d53f811ad6 to your computer and use it in GitHub Desktop.
ionic 3 interceptor
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