From 6129b07c4c2b22c2b61869bdd34367abfec4d43c Mon Sep 17 00:00:00 2001 From: Yogi_Wang Date: Mon, 25 Nov 2019 15:34:10 +0800 Subject: [PATCH] Reslove the token expired Signed-off-by: Yogi_Wang --- src/portal/src/app/app.module.ts | 6 +- .../src/app/intercept-http.service.spec.ts | 58 +++++++++++++++++++ src/portal/src/app/intercept-http.service.ts | 28 +++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/portal/src/app/intercept-http.service.spec.ts create mode 100644 src/portal/src/app/intercept-http.service.ts diff --git a/src/portal/src/app/app.module.ts b/src/portal/src/app/app.module.ts index c4709a6b1..8db97037c 100644 --- a/src/portal/src/app/app.module.ts +++ b/src/portal/src/app/app.module.ts @@ -14,6 +14,7 @@ import { BrowserModule } from '@angular/platform-browser'; import { NgModule, APP_INITIALIZER, LOCALE_ID, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { AppComponent } from './app.component'; +import { InterceptHttpService } from './intercept-http.service'; import { BaseModule } from './base/base.module'; import { HarborRoutingModule } from './harbor-routing.module'; @@ -42,6 +43,7 @@ import { LicenseModule } from './license/license.module'; import { InterrogationServicesComponent } from "./interrogation-services/interrogation-services.component"; import { LabelsComponent } from './labels/labels.component'; import { ProjectQuotasComponent } from './project-quotas/project-quotas.component'; +import { HTTP_INTERCEPTORS } from '@angular/common/http'; registerLocaleData(zh, 'zh-cn'); registerLocaleData(es, 'es-es'); @@ -93,7 +95,9 @@ export function getCurrentLanguage(translateService: TranslateService) { deps: [ AppConfigService, SkinableConfig], multi: true }, - {provide: LOCALE_ID, useValue: "en-US"} + {provide: LOCALE_ID, useValue: "en-US"}, + { provide: HTTP_INTERCEPTORS, useClass: InterceptHttpService, multi: true } + ], schemas: [ CUSTOM_ELEMENTS_SCHEMA diff --git a/src/portal/src/app/intercept-http.service.spec.ts b/src/portal/src/app/intercept-http.service.spec.ts new file mode 100644 index 000000000..4fe3c7b0f --- /dev/null +++ b/src/portal/src/app/intercept-http.service.spec.ts @@ -0,0 +1,58 @@ +import { TestBed, inject } from '@angular/core/testing'; + +import { InterceptHttpService } from './intercept-http.service'; +import { CookieService } from 'ngx-cookie'; +import { HttpRequest, HttpResponse } from '@angular/common/http'; +import { of, throwError } from 'rxjs'; + +describe('InterceptHttpService', () => { + let cookie = "fdsa|ds"; + const mockCookieService = { + get: function () { + return cookie; + }, + set: function (cookieStr: string) { + cookie = cookieStr; + } + }; + const mockRequest = new HttpRequest('PUT', "", { + headers: new Map() + }); + const mockHandle = { + handle: (request) => { + if (request.headers.has('X-Xsrftoken')) { + return of(new HttpResponse({status: 200})); + } else { + return throwError(new HttpResponse( { + status: 403 + })); + } + } + }; + beforeEach(() => TestBed.configureTestingModule({})); + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [], + providers: [ + InterceptHttpService, + { provide: CookieService, useValue: mockCookieService } + ] + }); + + }); + it('should be initialized', inject([InterceptHttpService], (service: InterceptHttpService) => { + expect(service).toBeTruthy(); + })); + + it('should be get right token and send right request when the cookie not exists', inject([InterceptHttpService], + (service: InterceptHttpService) => { + mockCookieService.set("fdsa|ds"); + service.intercept(mockRequest, mockHandle).subscribe(res => { + if (res.status === 403) { + expect(btoa(mockRequest.headers.get("X-Xsrftoken"))).toEqual(cookie.split("|")[0]); + } else { + expect(res.status).toEqual(200); + } + }); + })); +}); diff --git a/src/portal/src/app/intercept-http.service.ts b/src/portal/src/app/intercept-http.service.ts new file mode 100644 index 000000000..ae08e35df --- /dev/null +++ b/src/portal/src/app/intercept-http.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@angular/core'; +import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse } from '@angular/common/http'; +import { Observable, throwError } from 'rxjs'; +import { tap, catchError } from 'rxjs/operators'; +import { CookieService } from 'ngx-cookie'; + +@Injectable({ + providedIn: 'root' +}) +export class InterceptHttpService implements HttpInterceptor { + + constructor(private cookie: CookieService) { } + + intercept(request: HttpRequest, next: HttpHandler): Observable { + + return next.handle(request).pipe(catchError(error => { + if (error.status === 403) { + let Xsrftoken = this.cookie.get("_xsrf") ? atob(this.cookie.get("_xsrf").split("|")[0]) : null; + if (Xsrftoken && !request.headers.has('X-Xsrftoken')) { + request = request.clone({ headers: request.headers.set('X-Xsrftoken', Xsrftoken) }); + return next.handle(request); + } + } + return throwError(error); + })); + } +} +