Commit b75eec55 by Ooh-Ao

tokenservice httpinceptor

parent aff91f9f
......@@ -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,17 +45,18 @@ 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);
}
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);
}));
}
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 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 => {
this.isRefreshing = false;
this.refreshTokenSubject.next(newTokens.accessToken);
const token = this.tokenService.getRefreshToken();
const clonedReq = req.clone({
headers: req.headers.set('Authorization', `Bearer ${newTokens.accessToken}`)
});
return next.handle(clonedReq);
}),
catchError(err => {
this.isRefreshing = false;
this.authService.logout();
return throwError(() => new Error('Session expired, please log in again'));
})
);
if (token)
return this.authService.refreshToken(token.replace("Bearer ","")).pipe(
switchMap((token: any) => {
this.isRefreshing = false;
this.tokenService.saveToken(token.accessToken);
this.tokenService.saveRefreshToken(token.refreshToken);
this.refreshTokenSubject.next(token.accessToken);
return next.handle(this.addTokenHeader(request, token.accessToken ,fullUrl));
}),
catchError((err) => {
this.isRefreshing = false;
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 ;
return new UserLoginModel();
}
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