]>
Commit | Line | Data |
---|---|---|
d592e0a9 C |
1 | import { Injectable, Injector } from '@angular/core' |
2 | import { | |
3 | HttpInterceptor, | |
4 | HttpRequest, | |
5 | HttpEvent, | |
6 | HttpHandler, HTTP_INTERCEPTORS | |
7 | } from '@angular/common/http' | |
8 | import { Observable } from 'rxjs/Observable' | |
9 | ||
10 | import { AuthService } from '../../core' | |
11 | import 'rxjs/add/operator/switchMap' | |
12 | ||
13 | @Injectable() | |
14 | export class AuthInterceptor implements HttpInterceptor { | |
15 | private authService: AuthService | |
16 | ||
17 | // https://github.com/angular/angular/issues/18224#issuecomment-316957213 | |
18 | constructor (private injector: Injector) {} | |
19 | ||
20 | intercept (req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { | |
21 | if (this.authService === undefined) { | |
22 | this.authService = this.injector.get(AuthService) | |
23 | } | |
24 | ||
25 | const authReq = this.cloneRequestWithAuth(req) | |
26 | ||
27 | // Pass on the cloned request instead of the original request | |
28 | // Catch 401 errors (refresh token expired) | |
29 | return next.handle(authReq) | |
30 | .catch(err => { | |
cfe1efd2 | 31 | if (err.status === 401 && err.error && err.error.code === 'invalid_token') { |
d592e0a9 C |
32 | return this.handleTokenExpired(req, next) |
33 | } | |
34 | ||
35 | return Observable.throw(err) | |
36 | }) | |
37 | } | |
38 | ||
39 | private handleTokenExpired (req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { | |
40 | return this.authService.refreshAccessToken() | |
41 | .switchMap(() => { | |
42 | const authReq = this.cloneRequestWithAuth(req) | |
43 | ||
44 | return next.handle(authReq) | |
45 | }) | |
46 | } | |
47 | ||
48 | private cloneRequestWithAuth (req: HttpRequest<any>) { | |
49 | const authHeaderValue = this.authService.getRequestHeaderValue() | |
50 | ||
51 | if (authHeaderValue === null) return req | |
52 | ||
53 | // Clone the request to add the new header | |
54 | return req.clone({ headers: req.headers.set('Authorization', authHeaderValue) }) | |
55 | } | |
56 | } | |
57 | ||
58 | export const AUTH_INTERCEPTOR_PROVIDER = { | |
59 | provide: HTTP_INTERCEPTORS, | |
60 | useClass: AuthInterceptor, | |
61 | multi: true | |
62 | } |