diff options
Diffstat (limited to 'client/src/app/shared/auth/auth-interceptor.service.ts')
-rw-r--r-- | client/src/app/shared/auth/auth-interceptor.service.ts | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/client/src/app/shared/auth/auth-interceptor.service.ts b/client/src/app/shared/auth/auth-interceptor.service.ts new file mode 100644 index 000000000..1e890d8f3 --- /dev/null +++ b/client/src/app/shared/auth/auth-interceptor.service.ts | |||
@@ -0,0 +1,62 @@ | |||
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 => { | ||
31 | if (err.status === 401) { | ||
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 | } | ||