diff --git a/linktreeclone-backend/src/main/java/br/com/linktreeclone/exception/InvalidTokenException.java b/linktreeclone-backend/src/main/java/br/com/linktreeclone/exception/InvalidTokenException.java new file mode 100644 index 0000000..60c8921 --- /dev/null +++ b/linktreeclone-backend/src/main/java/br/com/linktreeclone/exception/InvalidTokenException.java @@ -0,0 +1,8 @@ +package br.com.linktreeclone.exception; + +public class InvalidTokenException extends RuntimeException +{ + public InvalidTokenException(String message) { + super(message); + } +} diff --git a/linktreeclone-backend/src/main/java/br/com/linktreeclone/exception/RestExceptionHandler.java b/linktreeclone-backend/src/main/java/br/com/linktreeclone/exception/RestExceptionHandler.java index 12c69e1..8782ca9 100644 --- a/linktreeclone-backend/src/main/java/br/com/linktreeclone/exception/RestExceptionHandler.java +++ b/linktreeclone-backend/src/main/java/br/com/linktreeclone/exception/RestExceptionHandler.java @@ -38,4 +38,16 @@ public ResponseEntity handleUnauthorizedException(UnauthorizedExc return new ResponseEntity<>(errorResponse, HttpStatus.FORBIDDEN); } + + @ExceptionHandler(InvalidTokenException.class) + public ResponseEntity handleInvalidTokenException(InvalidTokenException ex, WebRequest request) { + ErrorResponse errorResponse = new ErrorResponse( + LocalDateTime.now(), + HttpStatus.FORBIDDEN.value(), + "Forbidden", + ex.getMessage(), + request.getDescription(false).replace("uri=", "") + ); + return new ResponseEntity<>(errorResponse, HttpStatus.FORBIDDEN); + } } diff --git a/linktreeclone-backend/src/main/java/br/com/linktreeclone/security/TokenService.java b/linktreeclone-backend/src/main/java/br/com/linktreeclone/security/TokenService.java index c4193f2..0a59aec 100644 --- a/linktreeclone-backend/src/main/java/br/com/linktreeclone/security/TokenService.java +++ b/linktreeclone-backend/src/main/java/br/com/linktreeclone/security/TokenService.java @@ -1,6 +1,7 @@ package br.com.linktreeclone.security; import br.com.linktreeclone.entity.User; +import br.com.linktreeclone.exception.InvalidTokenException; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.security.Keys; @@ -53,7 +54,7 @@ public String validateToken(String token) .getSubject(); } catch (Exception e) { - throw new RuntimeException("Token JWT expirado ou inválido"); + throw new InvalidTokenException("Token JWT expirado ou inválido"); } } } \ No newline at end of file diff --git a/linktreeclone-frontend/src/api/axiosConfig.js b/linktreeclone-frontend/src/api/axiosConfig.js index 9e707df..2a967aa 100644 --- a/linktreeclone-frontend/src/api/axiosConfig.js +++ b/linktreeclone-frontend/src/api/axiosConfig.js @@ -1,7 +1,7 @@ import axios from 'axios'; const apiClient = axios.create({ - baseURL: 'https://linktree-clone-api-238899108893.southamerica-east1.run.app', + baseURL: 'https://linktree-clone-api-faw777jkuq-rj.a.run.app', }); @@ -15,4 +15,18 @@ apiClient.interceptors.request.use((config) => { return Promise.reject(error); }); +apiClient.interceptors.response.use( + (response) => { + return response; + }, + (error) => { + if (error.response && (error.response.status === 401 || error.response.status === 403)) { + localStorage.removeItem('authToken'); + window.location.href = '/login'; + console.log('Sessão expirada. Redirecionando para o login.'); + } + return Promise.reject(error); + } +); + export default apiClient; \ No newline at end of file