Commit 976d149a by Nakarin Luankla

refresh token

parent 61d7f206
......@@ -16,7 +16,7 @@ import { AngularFireDatabaseModule } from '@angular/fire/compat/database';
import { LeafletModule } from '@asymmetrik/ngx-leaflet';
import { environment } from 'src/environments/environment';
import { ColorPickerModule } from 'ngx-color-picker';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [AppComponent, CustomLayoutComponent, ContentLayoutComponent],
imports: [
......@@ -32,7 +32,8 @@ import { ColorPickerModule } from 'ngx-color-picker';
AngularFireAuthModule,
LeafletModule,
AngularFireModule.initializeApp(environment.firebase),
ColorPickerModule
ColorPickerModule,
HttpClientModule
],
providers: [],
......
......@@ -26,8 +26,8 @@ export class LoginPageComponent {
}
ngOnInit(): void {
this.loginForm = this.formBuilder.group({
username: ['spruko@admin.com', [Validators.required, Validators.email]],
password: ['sprukoadmin', Validators.required],
username: ['programmer', [Validators.required, Validators.email]],
password: ['147@P', Validators.required],
});
const authe: any = document.querySelector('.auth');
authe.setAttribute('class', 'h-full');
......
/* eslint-disable no-constant-condition */
import { Component, ElementRef } from '@angular/core';
import { NavService } from '../../services/navservice';
import { AuthService } from '../../services/auth.service';
@Component({
selector: 'app-header',
......@@ -10,11 +11,12 @@ import { NavService } from '../../services/navservice';
export class HeaderComponent {
constructor(public navServices: NavService,
private authService: AuthService,
private elementRef: ElementRef) {
}
logOut() {
sessionStorage.clear()
this.authService.logout();
}
themeChange(type: string, type1: string) {
......
......@@ -2,7 +2,7 @@ import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/compat/auth';
import { Router } from '@angular/router';
import { Observable } from 'rxjs';
import { BehaviorSubject, catchError, filter, Observable, switchMap, tap, throwError } from 'rxjs';
import { environment } from 'src/environments/environment';
@Injectable({
......@@ -12,13 +12,25 @@ export class AuthService {
authState: any;
api = "/authen"
urlApi = environment.baseUrl + this.api
constructor(private afu: AngularFireAuth, private router: Router, private http: HttpClient) {
this.afu.authState.subscribe((auth: any) => {
this.authState = auth;
});
}
// all firebase getdata functions
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);
})
);
}
get isUserAnonymousLoggedIn(): boolean {
return this.authState !== null ? this.authState.isAnonymous : false;
......@@ -77,6 +89,9 @@ export class AuthService {
}
return this.http.post<{ accessToken: string }>(this.urlApi + "/login", body)
}
logout(){
sessionStorage.clear()
}
singout(): void {
this.afu.signOut();
this.router.navigate(['/login']);
......
......@@ -6,32 +6,91 @@ import {
HttpInterceptor,
HttpErrorResponse
} from '@angular/common/http';
import { Observable, of, throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
import { BehaviorSubject, Observable, of, throwError } from 'rxjs';
import { catchError, filter, switchMap, take, tap } from 'rxjs/operators';
import { AuthService } from './auth.service';
@Injectable()
export class HttpRequestInterceptor {
responseCache = new Map()
constructor() { }
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)
// }));
// }
// }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.url.startsWith("./") || !sessionStorage.getItem("accessToken")) {
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)
}));
}
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 {
this.isRefreshing = true;
this.refreshTokenSubject.next(null);
return this.authService.refreshToken().pipe(
switchMap(newTokens => {
this.isRefreshing = false;
this.refreshTokenSubject.next(newTokens.accessToken);
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'));
})
);
}
}
}
......
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