1
- import { Injectable } from '@angular/core' ;
1
+ import { Injectable , OnDestroy } from '@angular/core' ;
2
2
import { Router } from '@angular/router' ;
3
3
import { HttpClient } from '@angular/common/http' ;
4
4
import { BehaviorSubject , Observable , of , Subscription } from 'rxjs' ;
5
5
import { map , tap , delay , finalize } from 'rxjs/operators' ;
6
6
import { ApplicationUser } from '../models/application-user' ;
7
7
import { environment } from 'src/environments/environment' ;
8
8
9
+ interface LoginResult {
10
+ username : string ;
11
+ role : string ;
12
+ accessToken : string ;
13
+ refreshToken : string ;
14
+ }
15
+
9
16
@Injectable ( {
10
17
providedIn : 'root' ,
11
18
} )
12
- export class AuthService {
19
+ export class AuthService implements OnDestroy {
13
20
private readonly apiUrl = `${ environment . apiUrl } api/account` ;
14
21
private timer : Subscription ;
15
22
private _user = new BehaviorSubject < ApplicationUser > ( null ) ;
16
- public user$ : Observable < ApplicationUser > = this . _user . asObservable ( ) ;
23
+ user$ : Observable < ApplicationUser > = this . _user . asObservable ( ) ;
24
+
25
+ private storageEventListener ( event : StorageEvent ) {
26
+ if ( event . storageArea === localStorage ) {
27
+ if ( event . key === 'logout-event' ) {
28
+ this . _user . next ( null ) ;
29
+ }
30
+ if ( event . key === 'login-event' ) {
31
+ location . reload ( ) ;
32
+ }
33
+ }
34
+ }
17
35
18
- constructor ( private router : Router , private http : HttpClient ) { }
36
+ constructor ( private router : Router , private http : HttpClient ) {
37
+ window . addEventListener ( 'storage' , this . storageEventListener . bind ( this ) ) ;
38
+ }
19
39
20
- public get currentUser ( ) : ApplicationUser {
21
- return this . _user . value ;
40
+ ngOnDestroy ( ) : void {
41
+ window . removeEventListener ( 'storage' , this . storageEventListener . bind ( this ) ) ;
22
42
}
23
43
24
44
login ( username : string , password : string ) {
25
45
return this . http
26
- . post < ApplicationUser > ( `${ this . apiUrl } /login` , { username, password } )
46
+ . post < LoginResult > ( `${ this . apiUrl } /login` , { username, password } )
27
47
. pipe (
28
- map ( ( user ) => {
29
- this . _user . next ( user ) ;
30
- this . setLocalStorage ( user ) ;
48
+ map ( ( x ) => {
49
+ this . _user . next ( { username : x . username , role : x . role } ) ;
50
+ this . setLocalStorage ( x ) ;
51
+ localStorage . setItem ( 'login-event' , 'login' + Math . random ( ) ) ;
31
52
this . startTokenTimer ( ) ;
32
- return user ;
53
+ return x ;
33
54
} )
34
55
) ;
35
56
}
@@ -40,9 +61,10 @@ export class AuthService {
40
61
. pipe (
41
62
finalize ( ( ) => {
42
63
this . clearLocalStorage ( ) ;
43
- this . stopTokenTimer ( ) ;
64
+ localStorage . setItem ( 'logout-event' , 'logout' + Math . random ( ) ) ;
44
65
this . _user . next ( null ) ;
45
- this . router . navigate ( [ '' ] ) ;
66
+ this . stopTokenTimer ( ) ;
67
+ this . router . navigate ( [ 'login' ] ) ;
46
68
} )
47
69
)
48
70
. subscribe ( ) ;
@@ -56,20 +78,20 @@ export class AuthService {
56
78
}
57
79
58
80
return this . http
59
- . post < ApplicationUser > ( `${ this . apiUrl } /refresh-token` , { refreshToken } )
81
+ . post < LoginResult > ( `${ this . apiUrl } /refresh-token` , { refreshToken } )
60
82
. pipe (
61
- map ( ( user ) => {
62
- this . _user . next ( user ) ;
63
- this . setLocalStorage ( user ) ;
83
+ map ( ( x ) => {
84
+ this . _user . next ( { username : x . username , role : x . role } ) ;
85
+ this . setLocalStorage ( x ) ;
64
86
this . startTokenTimer ( ) ;
65
- return user ;
87
+ return x ;
66
88
} )
67
89
) ;
68
90
}
69
91
70
- setLocalStorage ( user : ApplicationUser ) {
71
- localStorage . setItem ( 'access_token' , user . accessToken ) ;
72
- localStorage . setItem ( 'refresh_token' , user . refreshToken ) ;
92
+ setLocalStorage ( x : LoginResult ) {
93
+ localStorage . setItem ( 'access_token' , x . accessToken ) ;
94
+ localStorage . setItem ( 'refresh_token' , x . refreshToken ) ;
73
95
}
74
96
75
97
clearLocalStorage ( ) {
0 commit comments