Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mySkill-x
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
angular
mySkill-x
Commits
976d149a
Commit
976d149a
authored
Feb 19, 2025
by
Nakarin Luankla
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refresh token
parent
61d7f206
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
99 additions
and
22 deletions
+99
-22
app.module.ts
src/app/app.module.ts
+3
-2
login-page.component.ts
src/app/authentication/login-page/login-page.component.ts
+2
-2
header.component.ts
src/app/shared/components/header/header.component.ts
+3
-1
auth.service.ts
src/app/shared/services/auth.service.ts
+17
-2
http-request.interceptor.ts
src/app/shared/services/http-request.interceptor.ts
+74
-15
No files found.
src/app/app.module.ts
View file @
976d149a
...
@@ -16,7 +16,7 @@ import { AngularFireDatabaseModule } from '@angular/fire/compat/database';
...
@@ -16,7 +16,7 @@ import { AngularFireDatabaseModule } from '@angular/fire/compat/database';
import
{
LeafletModule
}
from
'@asymmetrik/ngx-leaflet'
;
import
{
LeafletModule
}
from
'@asymmetrik/ngx-leaflet'
;
import
{
environment
}
from
'src/environments/environment'
;
import
{
environment
}
from
'src/environments/environment'
;
import
{
ColorPickerModule
}
from
'ngx-color-picker'
;
import
{
ColorPickerModule
}
from
'ngx-color-picker'
;
import
{
HttpClientModule
}
from
'@angular/common/http'
;
@
NgModule
({
@
NgModule
({
declarations
:
[
AppComponent
,
CustomLayoutComponent
,
ContentLayoutComponent
],
declarations
:
[
AppComponent
,
CustomLayoutComponent
,
ContentLayoutComponent
],
imports
:
[
imports
:
[
...
@@ -32,7 +32,8 @@ import { ColorPickerModule } from 'ngx-color-picker';
...
@@ -32,7 +32,8 @@ import { ColorPickerModule } from 'ngx-color-picker';
AngularFireAuthModule
,
AngularFireAuthModule
,
LeafletModule
,
LeafletModule
,
AngularFireModule
.
initializeApp
(
environment
.
firebase
),
AngularFireModule
.
initializeApp
(
environment
.
firebase
),
ColorPickerModule
ColorPickerModule
,
HttpClientModule
],
],
providers
:
[],
providers
:
[],
...
...
src/app/authentication/login-page/login-page.component.ts
View file @
976d149a
...
@@ -26,8 +26,8 @@ export class LoginPageComponent {
...
@@ -26,8 +26,8 @@ export class LoginPageComponent {
}
}
ngOnInit
():
void
{
ngOnInit
():
void
{
this
.
loginForm
=
this
.
formBuilder
.
group
({
this
.
loginForm
=
this
.
formBuilder
.
group
({
username
:
[
'
spruko@admin.com
'
,
[
Validators
.
required
,
Validators
.
email
]],
username
:
[
'
programmer
'
,
[
Validators
.
required
,
Validators
.
email
]],
password
:
[
'
sprukoadmin
'
,
Validators
.
required
],
password
:
[
'
147@P
'
,
Validators
.
required
],
});
});
const
authe
:
any
=
document
.
querySelector
(
'.auth'
);
const
authe
:
any
=
document
.
querySelector
(
'.auth'
);
authe
.
setAttribute
(
'class'
,
'h-full'
);
authe
.
setAttribute
(
'class'
,
'h-full'
);
...
...
src/app/shared/components/header/header.component.ts
View file @
976d149a
/* eslint-disable no-constant-condition */
/* eslint-disable no-constant-condition */
import
{
Component
,
ElementRef
}
from
'@angular/core'
;
import
{
Component
,
ElementRef
}
from
'@angular/core'
;
import
{
NavService
}
from
'../../services/navservice'
;
import
{
NavService
}
from
'../../services/navservice'
;
import
{
AuthService
}
from
'../../services/auth.service'
;
@
Component
({
@
Component
({
selector
:
'app-header'
,
selector
:
'app-header'
,
...
@@ -10,11 +11,12 @@ import { NavService } from '../../services/navservice';
...
@@ -10,11 +11,12 @@ import { NavService } from '../../services/navservice';
export
class
HeaderComponent
{
export
class
HeaderComponent
{
constructor
(
public
navServices
:
NavService
,
constructor
(
public
navServices
:
NavService
,
private
authService
:
AuthService
,
private
elementRef
:
ElementRef
)
{
private
elementRef
:
ElementRef
)
{
}
}
logOut
()
{
logOut
()
{
sessionStorage
.
clear
()
this
.
authService
.
logout
();
}
}
themeChange
(
type
:
string
,
type1
:
string
)
{
themeChange
(
type
:
string
,
type1
:
string
)
{
...
...
src/app/shared/services/auth.service.ts
View file @
976d149a
...
@@ -2,7 +2,7 @@ import { HttpClient } from '@angular/common/http';
...
@@ -2,7 +2,7 @@ import { HttpClient } from '@angular/common/http';
import
{
Injectable
}
from
'@angular/core'
;
import
{
Injectable
}
from
'@angular/core'
;
import
{
AngularFireAuth
}
from
'@angular/fire/compat/auth'
;
import
{
AngularFireAuth
}
from
'@angular/fire/compat/auth'
;
import
{
Router
}
from
'@angular/router'
;
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'
;
import
{
environment
}
from
'src/environments/environment'
;
@
Injectable
({
@
Injectable
({
...
@@ -12,13 +12,25 @@ export class AuthService {
...
@@ -12,13 +12,25 @@ export class AuthService {
authState
:
any
;
authState
:
any
;
api
=
"/authen"
api
=
"/authen"
urlApi
=
environment
.
baseUrl
+
this
.
api
urlApi
=
environment
.
baseUrl
+
this
.
api
constructor
(
private
afu
:
AngularFireAuth
,
private
router
:
Router
,
private
http
:
HttpClient
)
{
constructor
(
private
afu
:
AngularFireAuth
,
private
router
:
Router
,
private
http
:
HttpClient
)
{
this
.
afu
.
authState
.
subscribe
((
auth
:
any
)
=>
{
this
.
afu
.
authState
.
subscribe
((
auth
:
any
)
=>
{
this
.
authState
=
auth
;
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
{
get
isUserAnonymousLoggedIn
():
boolean
{
return
this
.
authState
!==
null
?
this
.
authState
.
isAnonymous
:
false
;
return
this
.
authState
!==
null
?
this
.
authState
.
isAnonymous
:
false
;
...
@@ -77,6 +89,9 @@ export class AuthService {
...
@@ -77,6 +89,9 @@ export class AuthService {
}
}
return
this
.
http
.
post
<
{
accessToken
:
string
}
>
(
this
.
urlApi
+
"/login"
,
body
)
return
this
.
http
.
post
<
{
accessToken
:
string
}
>
(
this
.
urlApi
+
"/login"
,
body
)
}
}
logout
(){
sessionStorage
.
clear
()
}
singout
():
void
{
singout
():
void
{
this
.
afu
.
signOut
();
this
.
afu
.
signOut
();
this
.
router
.
navigate
([
'/login'
]);
this
.
router
.
navigate
([
'/login'
]);
...
...
src/app/shared/services/http-request.interceptor.ts
View file @
976d149a
...
@@ -6,32 +6,91 @@ import {
...
@@ -6,32 +6,91 @@ import {
HttpInterceptor
,
HttpInterceptor
,
HttpErrorResponse
HttpErrorResponse
}
from
'@angular/common/http'
;
}
from
'@angular/common/http'
;
import
{
Observable
,
of
,
throwError
}
from
'rxjs'
;
import
{
BehaviorSubject
,
Observable
,
of
,
throwError
}
from
'rxjs'
;
import
{
catchError
,
tap
}
from
'rxjs/operators'
;
import
{
catchError
,
filter
,
switchMap
,
take
,
tap
}
from
'rxjs/operators'
;
import
{
AuthService
}
from
'./auth.service'
;
@
Injectable
()
@
Injectable
()
export
class
HttpRequestInterceptor
{
export
class
HttpRequestInterceptor
{
responseCache
=
new
Map
()
private
isRefreshing
=
false
;
constructor
()
{
}
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
>>
{
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
);
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'
));
})
);
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment