Commit b75eec55 by Ooh-Ao

tokenservice httpinceptor

parent aff91f9f
......@@ -5,11 +5,7 @@
<div class="header-left">
<!-- Navigation Toggle -->
<div class="">
<button
type="button"
class="sidebar-toggle !w-100 !h-100"
(click)="toggleSidebar()"
>
<button type="button" class="sidebar-toggle !w-100 !h-100" (click)="toggleSidebar()">
<span class="sr-only">Toggle Navigation</span>
<i class="ri-arrow-right-circle-line header-icon"></i>
</button>
......@@ -41,29 +37,17 @@
<div class="header-right">
<div class="responsive-headernav">
<div class="header-nav-right">
<div
class="header-country hs-dropdown ti-dropdown hidden sm:block"
data-hs-dropdown-placement="bottom-right"
>
<button
id="dropdown-flag"
type="button"
class="hs-dropdown-toggle ti-dropdown-toggle p-0 flex-shrink-0 h-[2.375rem] w-[2.375rem] border-0 rounded-full shadow-none focus:ring-gray-400 text-xs dark:focus:ring-white/10"
>
<div class="header-country hs-dropdown ti-dropdown hidden sm:block"
data-hs-dropdown-placement="bottom-right">
<button id="dropdown-flag" type="button"
class="hs-dropdown-toggle ti-dropdown-toggle p-0 flex-shrink-0 h-[2.375rem] w-[2.375rem] border-0 rounded-full shadow-none focus:ring-gray-400 text-xs dark:focus:ring-white/10">
<i class="flag-icon flag-icon-th h-[1.375rem] w-[1.375rem]"></i>
</button>
<div
class="hs-dropdown-menu ti-dropdown-menu min-w-[10rem]"
aria-labelledby="dropdown-flag"
>
<div
class="ti-dropdown-divider divide-y divide-gray-200 dark:divide-white/10"
>
<div class="hs-dropdown-menu ti-dropdown-menu min-w-[10rem]" aria-labelledby="dropdown-flag">
<div class="ti-dropdown-divider divide-y divide-gray-200 dark:divide-white/10">
<div class="py-2 first:pt-0 last:pb-0">
<div class="ti-dropdown-item">
<div
class="flex items-center space-x-2 rtl:space-x-reverse w-full"
>
<div class="flex items-center space-x-2 rtl:space-x-reverse w-full">
<div class="h-[1.375rem] w-[1.375rem] rounded-sm">
<i class="flag-icon flag-icon-th"></i>
</div>
......@@ -73,9 +57,7 @@
</div>
</div>
<div class="ti-dropdown-item">
<div
class="flex items-center space-x-2 rtl:space-x-reverse w-full"
>
<div class="flex items-center space-x-2 rtl:space-x-reverse w-full">
<div class="h-[1.375rem] w-[1.375rem] rounded-sm">
<i class="flag-icon flag-icon-us"></i>
</div>
......@@ -681,40 +663,25 @@
</div>
</div>
</div> -->
<div
class="header-profile hs-dropdown ti-dropdown"
data-hs-dropdown-placement="bottom-right"
>
<button
id="dropdown-profile"
type="button"
class="hs-dropdown-toggle ti-dropdown-toggle gap-2 p-0 flex-shrink-0 h-8 w-8 rounded-full shadow-none focus:ring-gray-400 text-xs dark:focus:ring-white/10"
>
<img
class="inline-block rounded-full ring-2 ring-white dark:ring-white/10"
src="./assets/img/users/1.jpg"
alt="Image Description"
/>
<div class="header-profile hs-dropdown ti-dropdown" data-hs-dropdown-placement="bottom-right">
<button id="dropdown-profile" type="button"
class="hs-dropdown-toggle ti-dropdown-toggle gap-2 p-0 flex-shrink-0 h-8 w-8 rounded-full shadow-none focus:ring-gray-400 text-xs dark:focus:ring-white/10">
<img class="inline-block rounded-full ring-2 ring-white dark:ring-white/10"
src="./assets/img/users/1.jpg" alt="Image Description" />
</button>
<div
class="hs-dropdown-menu ti-dropdown-menu border-0 w-[20rem]"
aria-labelledby="dropdown-profile"
>
<div class="hs-dropdown-menu ti-dropdown-menu border-0 w-[20rem]" aria-labelledby="dropdown-profile">
<div class="ti-dropdown-header !bg-primary flex">
<div class="ltr:mr-3 rtl:ml-3">
<img
class="avatar shadow-none rounded-full !ring-transparent"
src="./assets/img/users/1.jpg"
alt="profile-img"
/>
<img class="avatar shadow-none rounded-full !ring-transparent" src="./assets/img/users/1.jpg"
alt="profile-img" />
</div>
<div>
<p class="ti-dropdown-header-title !text-white">
{{this.employeeProfile.thFullName?this.employeeProfile.thFullName:''}}
</p>
<p class="ti-dropdown-header-content !text-white/50 " style="font-size: 12px;">
{{tokenService.getUser().iss?tokenService.getUser().iss:''}}
{{tokenService.getUserData().position?tokenService.getUserData().position:'-'}}
</p>
</div>
</div>
......@@ -750,12 +717,9 @@
</div>
</div>
<div class="switcher-icon">
<button
aria-label="button"
type="button"
<button aria-label="button" type="button"
class="hs-dropdown-toggle inline-flex flex-shrink-0 justify-center items-center gap-2 h-[2.375rem] w-[2.375rem] rounded-full font-medium bg-gray-100 hover:bg-gray-200 text-gray-500 align-middle focus:outline-none focus-visible:outline-none focus:ring-0 focus:ring-gray-400 focus:ring-offset-0 focus:ring-offset-white transition-all text-xs dark:bg-bgdark dark:hover:bg-black/20 dark:text-white/70 dark:hover:text-white dark:focus:ring-white/10 dark:focus:ring-offset-white/10"
data-hs-overlay="#hs-overlay-switcher"
>
data-hs-overlay="#hs-overlay-switcher">
<i class="ri-settings-5-line header-icon animate-spin"></i>
</button>
</div>
......@@ -778,13 +742,8 @@
<div class="search-btn">
<i class="ri ri-search-2-line search-btn-icon"></i>
</div>
<input
type="text"
id="icon"
name="icon"
class="py-2 ltr:pl-11 rtl:pr-11 ti-form-input focus:z-10"
placeholder="Search by No. or Name"
/>
<input type="text" id="icon" name="icon" class="py-2 ltr:pl-11 rtl:pr-11 ti-form-input focus:z-10"
placeholder="Search by No. or Name" />
<div class="voice-search">
<i class="ri ri-mic-2-line voice-btn-icon"></i>
</div>
......@@ -794,140 +753,72 @@
</div>
</div>
<div class="mt-5">
<p
class="font-semibold text-[13px] text-gray-400 dark:text-gray-200 mb-2"
>
<p class="font-semibold text-[13px] text-gray-400 dark:text-gray-200 mb-2">
Are You Looking For...
</p>
<div
class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1"
id="badge1"
>
<a
routerLink="/page/team"
class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse"
>
<span class="inline-block text-secondary mr-1"
><i class="ri ri-user-line text-sm"></i
></span>
<div class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1" id="badge1">
<a routerLink="/page/team" class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse">
<span class="inline-block text-secondary mr-1"><i class="ri ri-user-line text-sm"></i></span>
Team
</a>
<a
href="javascript:void(0);"
<a href="javascript:void(0);"
class="header-remove-btn flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-secondary hover:bg-secondary hover:text-secondary focus:outline-none focus:bg-secondary focus:text-white"
(click)="removeRow('badge1')"
>
(click)="removeRow('badge1')">
<span class="sr-only">Remove badge</span>
<svg
class="h-4 w-4 hover:fill-white"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewBox="0 0 16 16"
>
<svg class="h-4 w-4 hover:fill-white" xmlns="http://www.w3.org/2000/svg" width="16" height="16"
fill="currentColor" viewBox="0 0 16 16">
<path
d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"
></path>
d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z">
</path>
</svg>
</a>
</div>
<div
id="badge2"
class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1"
>
<a
routerLink="/form-module/form-elements"
class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse"
>
<span class="inline-block text-secondary mr-1"
><i class="ri ri-file-text-line text-sm"></i
></span>
<div id="badge2" class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1">
<a routerLink="/form-module/form-elements"
class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse">
<span class="inline-block text-secondary mr-1"><i class="ri ri-file-text-line text-sm"></i></span>
Forms
</a>
<a
href="javascript:void(0);"
(click)="removeRow('badge2')"
class="header-remove-btn flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-secondary hover:bg-secondary hover:text-secondary focus:outline-none focus:bg-secondary focus:text-white"
>
<a href="javascript:void(0);" (click)="removeRow('badge2')"
class="header-remove-btn flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-secondary hover:bg-secondary hover:text-secondary focus:outline-none focus:bg-secondary focus:text-white">
<span class="sr-only">Remove badge</span>
<svg
class="h-4 w-4 hover:fill-white"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewBox="0 0 16 16"
>
<svg class="h-4 w-4 hover:fill-white" xmlns="http://www.w3.org/2000/svg" width="16" height="16"
fill="currentColor" viewBox="0 0 16 16">
<path
d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"
></path>
d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z">
</path>
</svg>
</a>
</div>
<div
id="badge3"
class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1"
>
<a
routerLink="/maps/leaflet"
class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse"
>
<span class="inline-block text-secondary mr-1"
><i class="ri ri-map-pin-line text-sm"></i
></span>
<div id="badge3" class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1">
<a routerLink="/maps/leaflet" class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse">
<span class="inline-block text-secondary mr-1"><i class="ri ri-map-pin-line text-sm"></i></span>
Maps
</a>
<a
href="javascript:void(0);"
(click)="removeRow('badge3')"
class="header-remove-btn flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-secondary hover:bg-secondary hover:text-secondary focus:outline-none focus:bg-secondary focus:text-white"
>
<a href="javascript:void(0);" (click)="removeRow('badge3')"
class="header-remove-btn flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-secondary hover:bg-secondary hover:text-secondary focus:outline-none focus:bg-secondary focus:text-white">
<span class="sr-only">Remove badge</span>
<svg
class="h-4 w-4 hover:fill-white"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewBox="0 0 16 16"
>
<svg class="h-4 w-4 hover:fill-white" xmlns="http://www.w3.org/2000/svg" width="16" height="16"
fill="currentColor" viewBox="0 0 16 16">
<path
d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"
></path>
d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z">
</path>
</svg>
</a>
</div>
<div
id="badge4"
class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1"
>
<a
routerLink="/widgets"
class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse"
>
<span class="inline-block text-secondary mr-1"
><i class="ri ri-server-line text-sm"></i
></span>
<div id="badge4" class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1">
<a routerLink="/widgets" class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse">
<span class="inline-block text-secondary mr-1"><i class="ri ri-server-line text-sm"></i></span>
Widgets
</a>
<a
href="javascript:void(0);"
(click)="removeRow('badge4')"
class="header-remove-btn flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-secondary hover:bg-secondary hover:text-secondary focus:outline-none focus:bg-secondary focus:text-white"
>
<a href="javascript:void(0);" (click)="removeRow('badge4')"
class="header-remove-btn flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-secondary hover:bg-secondary hover:text-secondary focus:outline-none focus:bg-secondary focus:text-white">
<span class="sr-only">Remove badge</span>
<svg
class="h-4 w-4 hover:fill-white"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewBox="0 0 16 16"
>
<svg class="h-4 w-4 hover:fill-white" xmlns="http://www.w3.org/2000/svg" width="16" height="16"
fill="currentColor" viewBox="0 0 16 16">
<path
d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"
></path>
d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z">
</path>
</svg>
</a>
</div>
......@@ -936,57 +827,33 @@
<p class="font-semibold text-sm text-gray-500 mb-2">
Recent Search :
</p>
<div
id="not1"
class="p-2 border dark:border-white/10 rounded-sm flex items-center text-gray-500 mb-1 relative header-box"
>
<a
routerLink="/advanced/notifications" (click)="removetheModal()"
class="w-full my-auto items-center flex"
>
<div id="not1"
class="p-2 border dark:border-white/10 rounded-sm flex items-center text-gray-500 mb-1 relative header-box">
<a routerLink="/advanced/notifications" (click)="removetheModal()" class="w-full my-auto items-center flex">
<span class="text-sm">Notifications</span>
</a>
<a
aria-label="anchor"
href="javascript:void(0);"
class="ltr:ml-auto rtl:mr-auto flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-gray-500 focus:outline-none header-remove-btn"
>
<a aria-label="anchor" href="javascript:void(0);"
class="ltr:ml-auto rtl:mr-auto flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-gray-500 focus:outline-none header-remove-btn">
<i class="ri-close-line" (click)="removeRow('not1')"></i>
</a>
</div>
<div
id="not2"
class="p-2 border dark:border-white/10 rounded-sm flex items-center text-gray-500 mb-1 relative header-box"
>
<a
routerLink="/components/alerts" (click)="removetheModal()"
class="w-full my-auto items-center flex"
>
<div id="not2"
class="p-2 border dark:border-white/10 rounded-sm flex items-center text-gray-500 mb-1 relative header-box">
<a routerLink="/components/alerts" (click)="removetheModal()" class="w-full my-auto items-center flex">
<span class="text-sm">Alerts</span>
</a>
<a
aria-label="anchor"
href="javascript:void(0);"
class="ltr:ml-auto rtl:mr-auto flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-gray-500 focus:outline-none header-remove-btn"
>
<a aria-label="anchor" href="javascript:void(0);"
class="ltr:ml-auto rtl:mr-auto flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-gray-500 focus:outline-none header-remove-btn">
<i class="ri-close-line" (click)="removeRow('not2')"></i>
</a>
</div>
<div
id="not3"
class="p-2 border dark:border-white/10 rounded-sm flex items-center text-gray-500 relative header-box"
>
<a
routerLink="/tables/basictables" (click)="removetheModal()"
class="w-full my-auto items-center flex"
>
<div id="not3"
class="p-2 border dark:border-white/10 rounded-sm flex items-center text-gray-500 relative header-box">
<a routerLink="/tables/basictables" (click)="removetheModal()" class="w-full my-auto items-center flex">
<span class="text-sm">Tables</span>
</a>
<a
aria-label="anchor"
href="javascript:void(0);"
class="ltr:ml-auto rtl:mr-auto flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-gray-500 focus:outline-none header-remove-btn"
>
<a aria-label="anchor" href="javascript:void(0);"
class="ltr:ml-auto rtl:mr-auto flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-gray-500 focus:outline-none header-remove-btn">
<i class="ri-close-line" (click)="removeRow('not3')"></i>
</a>
</div>
......@@ -994,16 +861,10 @@
</div>
<div class="ti-modal-footer">
<div class="inline-flex rounded-md shadow-sm">
<button
type="button"
class="ti-btn-group py-1 ti-btn-soft-primary dark:border-white/10"
>
<button type="button" class="ti-btn-group py-1 ti-btn-soft-primary dark:border-white/10">
Search
</button>
<button
type="button"
class="ti-btn-group py-1 ti-btn-primary dark:border-white/10"
>
<button type="button" class="ti-btn-group py-1 ti-btn-primary dark:border-white/10">
Clear Recents
</button>
</div>
......
......@@ -10,23 +10,15 @@ import { environment } from 'src/environments/environment';
})
export class AuthService {
authState: any;
api = "/auth"
urlApi = environment.baseUrl + this.api
apiBaseUrl = "/auth";
constructor( private router: Router, private http: HttpClient) {
constructor(private router: Router, private http: HttpClient) {
}
refreshToken(): Observable<{ accessToken: string; refreshToken: string }> {
return this.http.post<{ accessToken: string; refreshToken: string }>(
`${this.urlApi}/refresh-token`,
{ refreshToken: sessionStorage.getItem('refreshToken') }
).pipe(
tap(response => {
sessionStorage.setItem('accessToken', response.accessToken);
sessionStorage.setItem('refreshToken', response.refreshToken);
})
);
refreshToken(token: string) {
return this.http.post<any>(this.apiBaseUrl + "/refresh-token", {
"refreshToken": token
});
}
get isUserAnonymousLoggedIn(): boolean {
......@@ -53,14 +45,15 @@ export class AuthService {
}
}
loginWithUserPass(username: string, password: string): Observable<{ accessToken: string ,refreshToken:string}> {
loginWithUserPass(username: string, password: string): Observable<{ accessToken: string, refreshToken: string }> {
const body = {
username: username,
password: password
}
return this.http.post<{ accessToken: string, refreshToken: string }>(this.urlApi + "/login", body)
return this.http.post<{ accessToken: string, refreshToken: string }>(this.apiBaseUrl + "/login", body)
}
logout(){
logout() {
sessionStorage.clear()
localStorage.clear()
this.router.navigate(['/auth/login']);
......
......@@ -9,91 +9,80 @@ import {
import { BehaviorSubject, Observable, of, throwError } from 'rxjs';
import { catchError, filter, switchMap, take, tap } from 'rxjs/operators';
import { AuthService } from './auth.service';
import { environment } from 'src/environments/environment';
import { TokenService } from './token.service';
const TOKEN_HEADER_KEY = 'Authorization';
@Injectable()
export class HttpRequestInterceptor {
private isRefreshing = false;
private refreshTokenSubject: BehaviorSubject<string | null> = new BehaviorSubject<string | null>(null);
private responseCache = new Map<string, any>(); // ใช้เก็บ cache ของ response
constructor(private authService: AuthService) { }
// intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// if (req.url.startsWith("./") || !sessionStorage.getItem("accessToken")) {
// return next.handle(req);
// } else {
// const authHeader = 'Bearer ' + sessionStorage.getItem("accessToken")
// const overideReq = {
// headers: req.headers.set('Authorization', authHeader),
// url: req.url,
// };
// const authReq = req.clone(overideReq);
// return next.handle(authReq).pipe(tap(response => {
// this.responseCache.set(req.urlWithParams, response)
// }));
// }
// }
private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
constructor(private tokenService: TokenService, private authService: AuthService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.url.includes('/api/auth/refresh-token') || req.url.startsWith('./') || !sessionStorage.getItem('accessToken')) {
if (req.url.startsWith("./")) {
return next.handle(req);
} else {
let authReq = req;
const fullUrl = req.url.startsWith("http") ? req.url : environment.baseUrl + req.url;
const token = this.tokenService.getToken()
if (token != null && !req.url.includes("/refresh-token")) {
authReq = this.addTokenHeader(req, token ,fullUrl);
}else{
const overideReq = {
url: fullUrl,
};
authReq = req.clone(overideReq);
}
const authHeader = 'Bearer ' + sessionStorage.getItem('accessToken');
const clonedReq = req.clone({
headers: req.headers.set('Authorization', authHeader)
});
return next.handle(clonedReq).pipe(
tap(response => {
this.responseCache.set(req.urlWithParams, response); // เก็บ response cache
}),
catchError((error: HttpErrorResponse) => {
if (error.status === 401) {
return this.handle401Error(req, next);
return next.handle(authReq).pipe(catchError(error => {
if (error instanceof HttpErrorResponse && error.status === 403 && !fullUrl.includes("login")) {
return this.handle403Error(authReq, next ,fullUrl);
}
return throwError(() => error);
})
);
return throwError(error);
}));
}
private handle401Error(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.isRefreshing) {
return this.refreshTokenSubject.pipe(
filter(token => token !== null),
take(1),
switchMap(token => {
const clonedReq = req.clone({
headers: req.headers.set('Authorization', `Bearer ${token}`)
});
return next.handle(clonedReq);
})
);
} else {
}
private handle403Error(request: HttpRequest<any>, next: HttpHandler , fullUrl : string) {
if (!this.isRefreshing) {
this.isRefreshing = true;
this.refreshTokenSubject.next(null);
return this.authService.refreshToken().pipe(
switchMap(newTokens => {
const token = this.tokenService.getRefreshToken();
if (token)
return this.authService.refreshToken(token.replace("Bearer ","")).pipe(
switchMap((token: any) => {
this.isRefreshing = false;
this.refreshTokenSubject.next(newTokens.accessToken);
this.tokenService.saveToken(token.accessToken);
this.tokenService.saveRefreshToken(token.refreshToken);
this.refreshTokenSubject.next(token.accessToken);
const clonedReq = req.clone({
headers: req.headers.set('Authorization', `Bearer ${newTokens.accessToken}`)
});
return next.handle(clonedReq);
return next.handle(this.addTokenHeader(request, token.accessToken ,fullUrl));
}),
catchError(err => {
catchError((err) => {
this.isRefreshing = false;
this.authService.logout();
return throwError(() => new Error('Session expired, please log in again'));
this.tokenService.signOut();
return throwError(err);
})
);
}
}
}
return this.refreshTokenSubject.pipe(
filter(token => token !== null),
take(1),
switchMap((token) => next.handle(this.addTokenHeader(request, token ,fullUrl)))
);
}
private addTokenHeader(request: HttpRequest<any>, token: string ,fullUrl :string) {
/* for Spring Boot back-end */
// return request.clone({ headers: request.headers.set(TOKEN_HEADER_KEY, 'Bearer ' + token) });
/* for Node.js Express back-end */
return request.clone({ headers: request.headers.set(TOKEN_HEADER_KEY, token) , url : fullUrl });
}
}
import { Injectable } from '@angular/core';
import { EmployeeModel, MyEmployeeModel } from '../model/employee.model';
import { Router } from '@angular/router';
import { UserModel } from '../model/user.model';
const TOKEN_KEY = 'auth-token';
const REFRESHTOKEN_KEY = 'auth-refreshtoken';
const USER_KEY = 'auth-user';
const USER_DATA_KEY = 'auth-user-data';
export class UserLoginModel {
public username: string = "";
public accessToken: string = "";
public refreshToken: string = "";
}
const TOKEN_KEY = 'accessToken';
@Injectable({
providedIn: 'root'
providedIn: "root",
})
export class TokenService {
constructor(private router: Router) { }
constructor() {
signOut(): void {
window.localStorage.clear();
localStorage.clear();
this.router.navigate(["/auth/splash"]);
}
public saveToken(token: string): void {
window.localStorage.removeItem(TOKEN_KEY);
window.localStorage.setItem(TOKEN_KEY, token);
const user = this.getUser();
if (user.accessToken) {
this.saveUser({ ...user, accessToken: token });
}
}
public getUser(): any {
const user = this.decodeJWT(window.sessionStorage.getItem(TOKEN_KEY)!)
public saveUser(user: any): void {
window.localStorage.removeItem(USER_KEY);
window.localStorage.setItem(USER_KEY, JSON.stringify(user));
}
public getUser(): UserLoginModel {
const user = window.localStorage.getItem(USER_KEY);
if (user) {
return user;
return JSON.parse(user);
}
return new UserLoginModel();
}
return ;
public getToken(): string | null {
return window.localStorage.getItem(TOKEN_KEY);
}
decodeJWT(token: string) {
let base64Url = token.split('.')[1]; // ดึงส่วนที่เป็น Payload
let base64 = base64Url.replace('-', '+').replace('_', '/'); // แก้ไข base64 ให้ถูกต้อง
let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
return JSON.parse(jsonPayload);
public saveRefreshToken(token: string): void {
window.localStorage.removeItem(REFRESHTOKEN_KEY);
window.localStorage.setItem(REFRESHTOKEN_KEY, token);
}
public getRefreshToken(): string | null {
return window.localStorage.getItem(REFRESHTOKEN_KEY);
}
public saveUserData(user: string): void {
window.localStorage.removeItem(USER_DATA_KEY);
window.localStorage.setItem(USER_DATA_KEY, user);
}
public getUserData(): EmployeeModel {
// return window.localStorage.getItem(USER_DATA_KEY);
const user = window.localStorage.getItem(USER_DATA_KEY);
if (user) {
return new MyEmployeeModel(JSON.parse(user));
}
return new MyEmployeeModel();
}
}
......@@ -3,18 +3,7 @@
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false,
firebase: {
apiKey: '********************************',
authDomain: '********************************',
projectId: '********************************',
storageBucket: '********************************',
messagingSenderId: '********************************',
appId: '********************************',
measurementId: '********************************',
},
// baseUrl: 'https://hrplus-std.myhr.co.th/plus',
// baseUrl: 'https://192.168.10.165/plus',
baseUrl: ' https://myskill-x.myhr.co.th/api',
baseUrl: ' https://myskill-x-uat.myhr.co.th/api',
};
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment