First implementation of refresh token.
This commit is contained in:
@@ -8,6 +8,10 @@ export class JwtInterceptor implements HttpInterceptor {
|
||||
private readonly authenticationService = inject(AuthenticationService);
|
||||
|
||||
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||
if (this.authenticationService.isTokenExpired()) {
|
||||
this.authenticationService.renewToken();
|
||||
}
|
||||
|
||||
const jwt = this.authenticationService.getToken();
|
||||
|
||||
if (jwt) {
|
||||
@@ -16,6 +20,8 @@ export class JwtInterceptor implements HttpInterceptor {
|
||||
});
|
||||
|
||||
return next.handle(cloned);
|
||||
} else {
|
||||
this.authenticationService.unauthenticate();
|
||||
}
|
||||
|
||||
return next.handle(request);
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface RefreshTokenRequest {
|
||||
refreshTokenValue: string;
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { Injectable, inject } from "@angular/core";
|
||||
import { LoginRequest, LoginResponse } from "./model/login.model";
|
||||
import { lastValueFrom } from "rxjs";
|
||||
import { SigninRequest } from "./model/signin.model";
|
||||
import { RefreshTokenRequest } from "./model/refresh-token.model";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -17,4 +18,8 @@ export class UserRestService {
|
||||
signin(request: SigninRequest): Promise<void> {
|
||||
return lastValueFrom(this.httpClient.post<void>('/api/users', request));
|
||||
}
|
||||
|
||||
refreshToken(request: RefreshTokenRequest): Promise<LoginResponse> {
|
||||
return lastValueFrom(this.httpClient.post<LoginResponse>('/api/users/refresh-token', request));
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { inject, Injectable } from "@angular/core";
|
||||
import { User } from "../model/User";
|
||||
import { UserRestService } from "../rest-services/user/user.rest-service";
|
||||
import { RefreshTokenRequest } from "../rest-services/user/model/refresh-token.model";
|
||||
|
||||
const JWT_PARAM = 'jwt';
|
||||
const REFRESH_TOKEN_PARAM = 'refresh-token';
|
||||
|
||||
interface UserDetails {
|
||||
sub: string;
|
||||
@@ -15,8 +18,11 @@ interface UserDetails {
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthenticationService {
|
||||
authenticate(token: string): void {
|
||||
private userRestService = inject(UserRestService);
|
||||
|
||||
authenticate(token: string, refreshToken: string): void {
|
||||
localStorage.setItem(JWT_PARAM, token);
|
||||
localStorage.setItem(REFRESH_TOKEN_PARAM, refreshToken);
|
||||
}
|
||||
|
||||
unauthenticate(): void {
|
||||
@@ -44,6 +50,34 @@ export class AuthenticationService {
|
||||
return localStorage.getItem(JWT_PARAM) ?? undefined;
|
||||
}
|
||||
|
||||
isTokenExpired(): boolean {
|
||||
let result = false;
|
||||
|
||||
const userDetails = this.extractUserDetails();
|
||||
|
||||
if (userDetails) {
|
||||
const expirationDate = new Date(userDetails.exp * 1000);
|
||||
const now = new Date();
|
||||
|
||||
result = expirationDate < now;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
renewToken(): void {
|
||||
const refreshToken = localStorage.getItem(REFRESH_TOKEN_PARAM);
|
||||
if (refreshToken) {
|
||||
const request: RefreshTokenRequest = {
|
||||
refreshTokenValue: refreshToken
|
||||
};
|
||||
this.userRestService.refreshToken(request)
|
||||
.then(refreshTokenResponse => {
|
||||
this.authenticate(refreshTokenResponse.accessToken, refreshTokenResponse.refreshToken);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private extractUserFromLocalStorage(): User | undefined {
|
||||
let result: User | undefined = undefined;
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ export class LoginService {
|
||||
this.userRestService
|
||||
.login(state.request)
|
||||
.then((response) => {
|
||||
this.authenticationService.authenticate(response.accessToken);
|
||||
this.authenticationService.authenticate(response.accessToken, response.refreshToken);
|
||||
this.snackBar.open('Authentication succeeded!', 'Close', {
|
||||
duration: 5000,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user