feat: add auto refresh token service

This commit is contained in:
Polianin Nikita 2024-07-02 00:52:47 +03:00
parent ce5508fe7f
commit 0e4b57af51
2 changed files with 74 additions and 1 deletions

View File

@ -14,7 +14,8 @@ import {FocusNextDirective} from "@/directives/focus-next.directive";
<app-footer/>` <app-footer/>`
}) })
export class AppComponent { export class AppComponent {
constructor() { constructor(tokenRefreshService: TokenRefreshService) {
registerLocaleData(localeRu); registerLocaleData(localeRu);
tokenRefreshService.startTokenRefresh();
} }
} }

View File

@ -0,0 +1,72 @@
import {BehaviorSubject, interval, Subscription, switchMap} from "rxjs";
import {Injectable} from "@angular/core";
import {AuthService} from "@service/auth.service";
import {environment} from "@environment";
@Injectable({
providedIn: 'root',
})
export class TokenRefreshService {
private tokenRefreshSubscription: Subscription | undefined;
private tokenRefreshing$ = new BehaviorSubject<boolean>(false);
private refreshTokenExpireMs: number = environment.retryDelay;
constructor(private authService: AuthService) {
this.setRefreshTokenExpireMs(AuthService.tokenExpiresIn.getTime() - 1000 - Date.now());
authService.tokenChangeError.subscribe(_ => {
console.log('Token change error event received');
this.tokenRefreshing$.next(false);
this.stopTokenRefresh();
});
authService.expireTokenChange.subscribe(date => {
console.log('Expire token change event received:', date);
this.setRefreshTokenExpireMs(date.getTime() - 1000 - Date.now());
});
}
public startTokenRefresh(date: Date | null = null): void {
if (date)
this.refreshTokenExpireMs = new Date(date).getTime() - 1000 - Date.now();
if (!this.tokenRefreshSubscription || this.tokenRefreshSubscription.closed) {
this.tokenRefreshSubscription = interval(this.refreshTokenExpireMs).pipe(
switchMap(() => {
this.tokenRefreshing$.next(true);
return this.authService.refreshToken();
})
).subscribe({
next: (_) => {
this.tokenRefreshing$.next(false);
},
error: error => {
console.error('Token refresh error:', error);
this.tokenRefreshing$.next(false);
}
});
}
}
public getTokenRefreshing$(): BehaviorSubject<boolean> {
return this.tokenRefreshing$;
}
public stopTokenRefresh(): void {
if (this.tokenRefreshSubscription && !this.tokenRefreshSubscription.closed) {
this.tokenRefreshSubscription.unsubscribe();
this.tokenRefreshSubscription = undefined;
}
}
public setRefreshTokenExpireMs(expireMs: number): void {
if (expireMs < environment.retryDelay)
expireMs = 3000;
console.log(expireMs);
this.refreshTokenExpireMs = expireMs;
this.stopTokenRefresh();
this.startTokenRefresh();
}
}