From 7c515258415473747346e4b1e34ed6b7fb04323c Mon Sep 17 00:00:00 2001 From: Phet Date: Fri, 4 Oct 2024 16:54:41 +0700 Subject: [PATCH] [update] - add token exprire --- README.md | 1 + package-lock.json | 20 ++++++++ package.json | 1 + src/app/app.guard.ts | 32 ++++++------- src/app/app.module.ts | 24 +++++----- src/app/app.request.interceptor.ts | 29 +++++++++--- src/app/app.service.ts | 2 - src/app/auth/login/login.component.ts | 2 +- .../token-intercepter.interceptor.ts | 47 +++++++++---------- src/app/core/service/auth/auth.service.ts | 21 +++++---- .../core/service/auth/cathay-auth.service.ts | 7 +-- src/app/pages/@layouts/layouts.component.ts | 2 +- yarn.lock | 9 +++- 13 files changed, 121 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index 7104d95..3c8af98 100644 --- a/README.md +++ b/README.md @@ -25,3 +25,4 @@ Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To u ## Further help To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. +git push --mirror https://gitea.71dev.com/Phet/mirror-cathay.git diff --git a/package-lock.json b/package-lock.json index a7c3e75..5fbefde 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "@angular/platform-browser": "^15.2.0", "@angular/platform-browser-dynamic": "^15.2.0", "@angular/router": "^15.2.0", + "@auth0/angular-jwt": "^5.2.0", "@ng-select/ng-select": "^10.0.3", "bootstrap-icons": "^1.10.3", "date-fns": "^2.29.3", @@ -729,6 +730,17 @@ "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==", "dev": true }, + "node_modules/@auth0/angular-jwt": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@auth0/angular-jwt/-/angular-jwt-5.2.0.tgz", + "integrity": "sha512-9FS2L0QwGNlxA/zgeehCcsR9CZscouyXkoIj1fODM36A8BLfdzg9k9DWAXUQ2Drjk0AypGAFzeNZR4vsLMhdeQ==", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@angular/common": ">=14.0.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", @@ -13155,6 +13167,14 @@ "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==", "dev": true }, + "@auth0/angular-jwt": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@auth0/angular-jwt/-/angular-jwt-5.2.0.tgz", + "integrity": "sha512-9FS2L0QwGNlxA/zgeehCcsR9CZscouyXkoIj1fODM36A8BLfdzg9k9DWAXUQ2Drjk0AypGAFzeNZR4vsLMhdeQ==", + "requires": { + "tslib": "^2.0.0" + } + }, "@babel/code-frame": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", diff --git a/package.json b/package.json index a29227b..67c3a44 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@angular/platform-browser": "^15.2.0", "@angular/platform-browser-dynamic": "^15.2.0", "@angular/router": "^15.2.0", + "@auth0/angular-jwt": "^5.2.0", "@ng-select/ng-select": "^10.0.3", "bootstrap-icons": "^1.10.3", "date-fns": "^2.29.3", diff --git a/src/app/app.guard.ts b/src/app/app.guard.ts index d088422..514eea8 100644 --- a/src/app/app.guard.ts +++ b/src/app/app.guard.ts @@ -5,25 +5,25 @@ import { AppService } from './app.service'; @Injectable() export class AppGuard implements CanActivate, CanActivateChild { - constructor(private router: Router, private app: AppService) { - } + constructor(private router: Router, private app: AppService) { + } - canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { - return this.isLogin(); - } + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { + return this.isLogin(); + } - canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { - return this.isLogin(); - } + canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { + return this.isLogin(); + } - isLogin() { - return true; - // const user = this.app.auth(); - // if (!user) { - // this.router.navigate(['/auth/login']); - // return false; - // } - // return true; + isLogin() { + const user = this.app.auth(); + if (!user) { + this.router.navigate(['/auth/login'], { replaceUrl: true }); + localStorage.clear() + return false; } + return true; + } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 953a909..4ee10ed 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,14 +1,15 @@ -import {NgModule} from '@angular/core'; -import {BrowserModule} from '@angular/platform-browser'; -import {AppRoutingComponents, AppRoutingModule} from './app-routing.module'; -import {AppComponent} from './app.component'; +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { AppRoutingComponents, AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; -import {FormsModule, ReactiveFormsModule} from "@angular/forms"; -import {HTTP_INTERCEPTORS, HttpClientModule} from "@angular/common/http"; -import {AppService} from "./app.service"; -import {AppGuard} from "./app.guard"; -import {AppRequestInterceptor} from "./app.request.interceptor"; -import {AppSharedModule} from "./app.shared"; +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { HTTP_INTERCEPTORS, HttpClientModule } from "@angular/common/http"; +import { AppService } from "./app.service"; +import { AppGuard } from "./app.guard"; +import { AppRequestInterceptor } from "./app.request.interceptor"; +import { AppSharedModule } from "./app.shared"; +import { JwtModule } from '@auth0/angular-jwt'; @NgModule({ @@ -24,7 +25,8 @@ import {AppSharedModule} from "./app.shared"; FormsModule, ReactiveFormsModule, HttpClientModule, - AppSharedModule + AppSharedModule, + JwtModule ], providers: [ AppService, diff --git a/src/app/app.request.interceptor.ts b/src/app/app.request.interceptor.ts index 8d178ed..ea8d6e6 100644 --- a/src/app/app.request.interceptor.ts +++ b/src/app/app.request.interceptor.ts @@ -1,23 +1,40 @@ import { Injectable } from '@angular/core'; -import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; +import { HttpContextToken, HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; import { Router } from '@angular/router'; import { AppService } from './app.service'; import { catchError, Observable, throwError } from 'rxjs'; import { environment } from 'src/environments/environment'; import { SathonCathayPayService } from './sathon-cathay-pay.service'; - +import { JwtHelperService } from '@auth0/angular-jwt'; +export const SKIP_INTERCEP = new HttpContextToken(() => false); @Injectable() export class AppRequestInterceptor implements HttpInterceptor { constructor( private router: Router, private appService: AppService, - private sathonSV: SathonCathayPayService - ) { + // private sathonSV: SathonCathayPayService + ) { } - } intercept(request: HttpRequest, next: HttpHandler): Observable> { + + if (request.context.get(SKIP_INTERCEP)) { + return next.handle(request) + } + const token = this.appService.token(); + const appsathonAPpToken = this.appService.getsathonToken() + + + const helper = new JwtHelperService(); + const isAppTokenExpired = helper.isTokenExpired(token); + const isSathonAppTokenExpired = helper.isTokenExpired(appsathonAPpToken) + + if (isAppTokenExpired || isSathonAppTokenExpired) { + this.router.navigate(['/auth'], { replaceUrl: true }); + localStorage.clear() + return + } if (token) { request = request.clone({ @@ -29,7 +46,7 @@ export class AppRequestInterceptor implements HttpInterceptor { catchError((err) => { if (err instanceof HttpErrorResponse) { if (err.status === 401) { - this.router.navigate(['/auth']); + this.router.navigate(['/auth'], { replaceUrl: true }); } } return throwError(err); diff --git a/src/app/app.service.ts b/src/app/app.service.ts index f0db129..db2c810 100644 --- a/src/app/app.service.ts +++ b/src/app/app.service.ts @@ -4,8 +4,6 @@ import { DOCUMENT, Location } from '@angular/common'; import { from, Observable } from 'rxjs'; import Swal, { SweetAlertResult } from 'sweetalert2' import { EAction } from "./@config/app"; - - @Injectable() export class AppService { diff --git a/src/app/auth/login/login.component.ts b/src/app/auth/login/login.component.ts index 6846de7..827e5be 100644 --- a/src/app/auth/login/login.component.ts +++ b/src/app/auth/login/login.component.ts @@ -55,7 +55,7 @@ export class LoginComponent implements OnInit { isAdmin: isAdmin } - this.appService.setToken(cathayResult.token.token) + this.appService.setToken(cathayResult.token) this.appService.setSathonToken(sathonToken.token) this.appService.setAuth(cathayResult); diff --git a/src/app/core/intercepter/token-intercepter.interceptor.ts b/src/app/core/intercepter/token-intercepter.interceptor.ts index 81e05a4..d1f162b 100644 --- a/src/app/core/intercepter/token-intercepter.interceptor.ts +++ b/src/app/core/intercepter/token-intercepter.interceptor.ts @@ -1,9 +1,9 @@ import { Injectable } from '@angular/core'; import { - HttpRequest, - HttpHandler, - HttpEvent, - HttpInterceptor + HttpRequest, + HttpHandler, + HttpEvent, + HttpInterceptor } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { catchError, finalize } from 'rxjs/operators'; @@ -12,26 +12,23 @@ import { Router } from '@angular/router'; @Injectable() export class TokenIntercepterInterceptor implements HttpInterceptor { - constructor( - private router: Router, - ) { - } + constructor() { } - intercept(request: HttpRequest, next: HttpHandler): Observable> { - const customReq = request.clone({ - setHeaders: { - // Authorization: request.url.includes('app_tokens') ? `${this.odicSV.getAuthorizationHeaderValue()}` : `Bearer ${this.appTokenSV.getToken()}` - } - }); - return next.handle(customReq) - // return next.handle(customReq).pipe( - // finalize(() => this.progress.ref('progressBar').complete()), - // catchError(err => { - // if (err.status == 401) { - // this.router.navigate(['./'], { replaceUrl: true }) - // } - // return throwError(err) - // }) - // ); - } + intercept(request: HttpRequest, next: HttpHandler): Observable> { + const customReq = request.clone({ + setHeaders: { + // Authorization: request.url.includes('app_tokens') ? `${this.odicSV.getAuthorizationHeaderValue()}` : `Bearer ${this.appTokenSV.getToken()}` + } + }); + return next.handle(customReq) + // return next.handle(customReq).pipe( + // finalize(() => this.progress.ref('progressBar').complete()), + // catchError(err => { + // if (err.status == 401) { + // this.router.navigate(['./'], { replaceUrl: true }) + // } + // return throwError(err) + // }) + // ); + } } diff --git a/src/app/core/service/auth/auth.service.ts b/src/app/core/service/auth/auth.service.ts index 49c6466..42965e5 100644 --- a/src/app/core/service/auth/auth.service.ts +++ b/src/app/core/service/auth/auth.service.ts @@ -1,20 +1,21 @@ -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpContext } from '@angular/common/http'; import { Injectable } from '@angular/core'; +import { SKIP_INTERCEP } from 'src/app/app.request.interceptor'; import { BaseService } from 'src/app/core/base/base-service'; @Injectable({ providedIn: 'root' }) -export class AuthService extends BaseService{ +export class AuthService extends BaseService { - constructor( - public http: HttpClient - ) { - super('/common/user_login', http) - } + constructor( + public http: HttpClient + ) { + super('/common/user_login', http) + } - login(payload : {'loginname': string , 'password' : string}){ - return this.http.get(`${this.prefix}/common/user_login/login/${payload.loginname}/${payload.password}`) - } + login(payload: { 'loginname': string, 'password': string }) { + return this.http.get(`${this.prefix}/common/user_login/login/${payload.loginname}/${payload.password}`) + } } diff --git a/src/app/core/service/auth/cathay-auth.service.ts b/src/app/core/service/auth/cathay-auth.service.ts index 7ec9fd3..a8d6522 100644 --- a/src/app/core/service/auth/cathay-auth.service.ts +++ b/src/app/core/service/auth/cathay-auth.service.ts @@ -1,5 +1,6 @@ -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpContext, HttpContextToken } from '@angular/common/http'; import { Injectable } from '@angular/core'; +import { SKIP_INTERCEP } from 'src/app/app.request.interceptor'; import { BaseService } from 'src/app/core/base/base-service'; import { environment } from 'src/environments/environment'; @@ -16,11 +17,11 @@ export class CathayAuthService extends BaseService { } login(payload: { 'mobileDeviceId': string, 'userName': string, 'password': string }) { - return this.http.post(`${this.fullUrl}/login`, payload) + return this.http.post(`${this.fullUrl}/login`, payload, { context: new HttpContext().set(SKIP_INTERCEP, true) }) } // https://sathorn.cathay-pay.com/api/v3/User/login genToken() { - return this.http.get(`${environment.APIURL}/api/common/user_login/token`) + return this.http.get(`${environment.APIURL}/api/common/user_login/token`, { context: new HttpContext().set(SKIP_INTERCEP, true) }) } } diff --git a/src/app/pages/@layouts/layouts.component.ts b/src/app/pages/@layouts/layouts.component.ts index 09546ed..8b11ffe 100644 --- a/src/app/pages/@layouts/layouts.component.ts +++ b/src/app/pages/@layouts/layouts.component.ts @@ -38,7 +38,7 @@ export class PagesLayoutsComponent implements OnInit { // console.log(this.auth) // console.log(this.auth.isAdmin) this.menus = this.menus.map(r => { - if (this.auth.isAdmin) { + if (this.auth?.isAdmin) { if (r.roles.includes(ROLE_ADMIN)) return { ...r, children: r.children.length ? r.children.filter(c => r.roles.includes(ROLE_ADMIN)) : [] diff --git a/yarn.lock b/yarn.lock index 5e6d917..e795bc8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -280,6 +280,13 @@ resolved "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.10.1.tgz" integrity sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg== +"@auth0/angular-jwt@^5.2.0": + version "5.2.0" + resolved "https://registry.npmjs.org/@auth0/angular-jwt/-/angular-jwt-5.2.0.tgz" + integrity sha512-9FS2L0QwGNlxA/zgeehCcsR9CZscouyXkoIj1fODM36A8BLfdzg9k9DWAXUQ2Drjk0AypGAFzeNZR4vsLMhdeQ== + dependencies: + tslib "^2.0.0" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6": version "7.18.6" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz" @@ -6622,7 +6629,7 @@ tslib@^1.9.0: resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@2.5.0: +tslib@^2.0.0, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@2.5.0: version "2.5.0" resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz" integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==