4 Commits

Author SHA1 Message Date
Hanif Hakim
f430a2239a Refactor : More informative exception for Token Validation 2024-01-21 17:17:22 +07:00
Hanif Hakim
c607230f51 Rearrange project structure 2024-01-20 20:56:02 +07:00
Hanif Fauzi Hakim
0308a33594 Merge pull request #2 from hakimfauzi23/with-http-headers
Add Readme.md & update application.properties
2024-01-07 12:41:04 +07:00
Hanif Fauzi Hakim
af945478b5 Merge pull request #1 from hakimfauzi23/with-http-headers
Change from Http Cookies to Http Headers JWT Mechanism
2024-01-04 13:35:17 +07:00
30 changed files with 216 additions and 127 deletions

View File

@@ -1,8 +1,8 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth;
package com.hakimfauzi23.boilerplatespringsecurity;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.jwt.AuthEntryPointJwt;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.jwt.AuthTokenFilter;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.service.UserDetailsServiceImpl;
import com.hakimfauzi23.boilerplatespringsecurity.jwt.AuthEntryPointJwt;
import com.hakimfauzi23.boilerplatespringsecurity.jwt.AuthTokenFilter;
import com.hakimfauzi23.boilerplatespringsecurity.service.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@@ -1,32 +1,36 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.controllers;
package com.hakimfauzi23.boilerplatespringsecurity.controllers;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.ERole;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.RefreshToken;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.Role;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.User;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.request.LoginRequest;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.request.SignupRequest;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.request.TokenRefreshRequest;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.response.JwtResponse;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.response.MessageResponse;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.response.TokenRefreshResponse;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.jwt.JwtUtils;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.jwt.exception.TokenRefreshException;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.repository.RoleRepository;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.repository.UserRepository;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.service.RefreshTokenService;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.service.UserDetailsImpl;
import com.hakimfauzi23.boilerplatespringsecurity.data.ERole;
import com.hakimfauzi23.boilerplatespringsecurity.data.RefreshToken;
import com.hakimfauzi23.boilerplatespringsecurity.data.Role;
import com.hakimfauzi23.boilerplatespringsecurity.data.User;
import com.hakimfauzi23.boilerplatespringsecurity.data.payload.request.LoginRequest;
import com.hakimfauzi23.boilerplatespringsecurity.data.payload.request.SignupRequest;
import com.hakimfauzi23.boilerplatespringsecurity.data.payload.request.TokenRefreshRequest;
import com.hakimfauzi23.boilerplatespringsecurity.data.payload.response.JwtResponse;
import com.hakimfauzi23.boilerplatespringsecurity.data.payload.response.MessageResponse;
import com.hakimfauzi23.boilerplatespringsecurity.data.payload.response.TokenRefreshResponse;
import com.hakimfauzi23.boilerplatespringsecurity.exception.exception.SignInException;
import com.hakimfauzi23.boilerplatespringsecurity.jwt.JwtUtils;
import com.hakimfauzi23.boilerplatespringsecurity.exception.exception.TokenRefreshException;
import com.hakimfauzi23.boilerplatespringsecurity.repository.RoleRepository;
import com.hakimfauzi23.boilerplatespringsecurity.repository.UserRepository;
import com.hakimfauzi23.boilerplatespringsecurity.service.RefreshTokenService;
import com.hakimfauzi23.boilerplatespringsecurity.service.UserDetailsImpl;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -100,26 +104,32 @@ public class AuthController {
@PostMapping("/signin")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
try {
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtUtils.generateJwtToken(authentication);
Authentication authentication = authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
List<String> roles = userDetails.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.toList());
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtUtils.generateJwtToken(authentication);
RefreshToken refreshToken = refreshTokenService.createRefreshToken(userDetails.getId());
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
List<String> roles = userDetails.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.toList());
RefreshToken refreshToken = refreshTokenService.createRefreshToken(userDetails.getId());
return ResponseEntity.ok(new JwtResponse(
jwt,
refreshToken.getToken(),
userDetails.getId(),
userDetails.getUsername(),
userDetails.getEmail(),
roles));
} catch (AuthenticationException exception) {
throw new SignInException(exception.getMessage());
}
return ResponseEntity.ok(new JwtResponse(
jwt,
refreshToken.getToken(),
userDetails.getId(),
userDetails.getUsername(),
userDetails.getEmail(),
roles));
}
@PostMapping("/refresh-token")

View File

@@ -1,4 +1,4 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.controllers;
package com.hakimfauzi23.boilerplatespringsecurity.controllers;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.CrossOrigin;

View File

@@ -0,0 +1,6 @@
package com.hakimfauzi23.boilerplatespringsecurity.data;
public enum ERole {
ROLE_USER,
ROLE_ADMIN
}

View File

@@ -1,4 +1,4 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data;
package com.hakimfauzi23.boilerplatespringsecurity.data;
import jakarta.persistence.*;

View File

@@ -1,4 +1,4 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data;
package com.hakimfauzi23.boilerplatespringsecurity.data;
import jakarta.persistence.*;

View File

@@ -1,4 +1,4 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data;
package com.hakimfauzi23.boilerplatespringsecurity.data;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;

View File

@@ -1,4 +1,4 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.request;
package com.hakimfauzi23.boilerplatespringsecurity.data.payload.request;
import jakarta.validation.constraints.NotBlank;

View File

@@ -1,4 +1,4 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.request;
package com.hakimfauzi23.boilerplatespringsecurity.data.payload.request;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;

View File

@@ -1,4 +1,4 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.request;
package com.hakimfauzi23.boilerplatespringsecurity.data.payload.request;
import jakarta.validation.constraints.NotBlank;

View File

@@ -1,4 +1,4 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.response;
package com.hakimfauzi23.boilerplatespringsecurity.data.payload.response;
import java.util.List;

View File

@@ -1,4 +1,4 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.response;
package com.hakimfauzi23.boilerplatespringsecurity.data.payload.response;
public class MessageResponse {
private String message;

View File

@@ -1,4 +1,4 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.response;
package com.hakimfauzi23.boilerplatespringsecurity.data.payload.response;
public class TokenRefreshResponse {

View File

@@ -0,0 +1,39 @@
package com.hakimfauzi23.boilerplatespringsecurity.exception.advice;
import com.hakimfauzi23.boilerplatespringsecurity.exception.exception.ErrorMessage;
import com.hakimfauzi23.boilerplatespringsecurity.exception.exception.SignInException;
import com.hakimfauzi23.boilerplatespringsecurity.exception.exception.TokenRefreshException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import java.util.Date;
@RestControllerAdvice
public class AuthControllerAdvice {
@ExceptionHandler(value = SignInException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ErrorMessage handleLoginException(SignInException ex, WebRequest request) {
return new ErrorMessage(
HttpStatus.BAD_REQUEST.value(),
new Date(),
ex.getMessage(),
request.getDescription(false)
);
}
@ExceptionHandler(value = TokenRefreshException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public ErrorMessage handleTokenRefreshException(TokenRefreshException ex, WebRequest request) {
return new ErrorMessage(
HttpStatus.FORBIDDEN.value(),
new Date(),
ex.getMessage(),
request.getDescription(false)
);
}
}

View File

@@ -1,4 +1,4 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.jwt.exception;
package com.hakimfauzi23.boilerplatespringsecurity.exception.exception;
import java.util.Date;

View File

@@ -0,0 +1,14 @@
package com.hakimfauzi23.boilerplatespringsecurity.exception.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class SignInException extends RuntimeException {
private static final long serialVersionUID = 1L;
public SignInException(String message) {
super(message);
}
}

View File

@@ -1,4 +1,4 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.jwt.exception;
package com.hakimfauzi23.boilerplatespringsecurity.exception.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

View File

@@ -0,0 +1,13 @@
package com.hakimfauzi23.boilerplatespringsecurity.exception.exception;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public class TokenValidationException extends AuthenticationException {
public TokenValidationException(String message) {
super(message);
}
}

View File

@@ -1,17 +1,23 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.jwt;
package com.hakimfauzi23.boilerplatespringsecurity.jwt;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.hakimfauzi23.boilerplatespringsecurity.exception.exception.ErrorMessage;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@@ -25,14 +31,22 @@ public class AuthEntryPointJwt implements AuthenticationEntryPoint {
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
ErrorMessage body = new ErrorMessage(
HttpStatus.UNAUTHORIZED.value(),
new Date(),
"General Authentication Error (Invalid JWT, Unknown JWT Format), Please get new JWT Token!",
String.format("uri=%s", request.getRequestURI())
);
final Map<String, Object> body = new HashMap<>();
body.put("status", HttpServletResponse.SC_UNAUTHORIZED);
body.put("error", "Unauthorized");
body.put("message", authException.getMessage());
body.put("path", request.getServletPath());
final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
mapper.setDateFormat(dateFormat);
mapper.writeValue(response.getOutputStream(), body);
}
}

View File

@@ -1,11 +1,18 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.jwt;
package com.hakimfauzi23.boilerplatespringsecurity.jwt;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.service.UserDetailsServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.hakimfauzi23.boilerplatespringsecurity.exception.exception.ErrorMessage;
import com.hakimfauzi23.boilerplatespringsecurity.exception.exception.TokenValidationException;
import com.hakimfauzi23.boilerplatespringsecurity.service.UserDetailsServiceImpl;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
@@ -14,6 +21,8 @@ import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class AuthTokenFilter extends OncePerRequestFilter {
@@ -28,6 +37,7 @@ public class AuthTokenFilter extends OncePerRequestFilter {
throws ServletException, IOException {
try {
String jwt = parseJwt(request);
if (jwt != null && jwtUtils.validateJwtToken(jwt)) {
String username = jwtUtils.getUserNameFromJwtToken(jwt);
@@ -42,8 +52,25 @@ public class AuthTokenFilter extends OncePerRequestFilter {
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (Exception e) {
logger.error("Cannot set user authentication: {}", e);
} catch (TokenValidationException e) {
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
ErrorMessage body = new ErrorMessage(
HttpStatus.UNAUTHORIZED.value(),
new Date(),
e.getMessage(),
String.format("uri=%s", request.getRequestURI())
);
final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
mapper.setDateFormat(dateFormat);
mapper.writeValue(response.getOutputStream(), body);
return;
}
filterChain.doFilter(request, response);

View File

@@ -1,19 +1,16 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.jwt;
package com.hakimfauzi23.boilerplatespringsecurity.jwt;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.User;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.service.UserDetailsImpl;
import com.hakimfauzi23.boilerplatespringsecurity.exception.exception.TokenValidationException;
import com.hakimfauzi23.boilerplatespringsecurity.service.UserDetailsImpl;
import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import io.jsonwebtoken.security.SignatureException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseCookie;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import org.springframework.web.util.WebUtils;
import java.security.Key;
import java.util.Date;
@@ -54,21 +51,16 @@ public class JwtUtils {
.parseClaimsJws(token).getBody().getSubject();
}
public boolean validateJwtToken(String authToken) {
public boolean validateJwtToken(String authToken) throws TokenValidationException {
try {
Jwts.parserBuilder().setSigningKey(key()).build().parse(authToken);
return true;
} catch (MalformedJwtException e) {
} catch (MalformedJwtException | ExpiredJwtException | UnsupportedJwtException | IllegalArgumentException |
SignatureException e) {
LOGGER.error("Invalid JWT token: {}", e.getMessage());
} catch (ExpiredJwtException e) {
LOGGER.error("JWT token is expired: {}", e.getMessage());
} catch (UnsupportedJwtException e) {
LOGGER.error("JWT token is unsupported: {}", e.getMessage());
} catch (IllegalArgumentException e) {
LOGGER.error("JWT claims string is empty: {}", e.getMessage());
throw new TokenValidationException(e.getMessage());
}
return false;
}
}

View File

@@ -1,6 +0,0 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data;
public enum ERole {
ROLE_USER,
ROLE_ADMIN
}

View File

@@ -1,26 +0,0 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.jwt.advice;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.jwt.exception.ErrorMessage;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.jwt.exception.TokenRefreshException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import java.util.Date;
@RestControllerAdvice
public class TokenControllerAdvice {
@ExceptionHandler(value = TokenRefreshException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public ErrorMessage handleTokenRefreshException(TokenRefreshException ex, WebRequest request) {
return new ErrorMessage(
HttpStatus.FORBIDDEN.value(),
new Date(),
ex.getMessage(),
request.getDescription(false)
);
}
}

View File

@@ -1,7 +1,7 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.repository;
package com.hakimfauzi23.boilerplatespringsecurity.repository;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.RefreshToken;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.User;
import com.hakimfauzi23.boilerplatespringsecurity.data.RefreshToken;
import com.hakimfauzi23.boilerplatespringsecurity.data.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Repository;
@@ -13,6 +13,9 @@ public interface RefreshTokenRepository extends JpaRepository<RefreshToken, Long
Optional<RefreshToken> findByToken(String token);
Optional<RefreshToken> findByUserId(Long userId);
@Modifying
int deleteByUser(User user);
}

View File

@@ -1,7 +1,7 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.repository;
package com.hakimfauzi23.boilerplatespringsecurity.repository;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.ERole;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.Role;
import com.hakimfauzi23.boilerplatespringsecurity.data.ERole;
import com.hakimfauzi23.boilerplatespringsecurity.data.Role;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

View File

@@ -1,6 +1,6 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.repository;
package com.hakimfauzi23.boilerplatespringsecurity.repository;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.User;
import com.hakimfauzi23.boilerplatespringsecurity.data.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

View File

@@ -1,9 +1,10 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.service;
package com.hakimfauzi23.boilerplatespringsecurity.service;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.RefreshToken;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.jwt.exception.TokenRefreshException;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.repository.RefreshTokenRepository;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.repository.UserRepository;
import com.hakimfauzi23.boilerplatespringsecurity.data.RefreshToken;
import com.hakimfauzi23.boilerplatespringsecurity.exception.exception.SignInException;
import com.hakimfauzi23.boilerplatespringsecurity.exception.exception.TokenRefreshException;
import com.hakimfauzi23.boilerplatespringsecurity.repository.RefreshTokenRepository;
import com.hakimfauzi23.boilerplatespringsecurity.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@@ -30,8 +31,10 @@ public class RefreshTokenService {
}
public RefreshToken createRefreshToken(Long userId) {
RefreshToken refreshToken = new RefreshToken();
Optional<RefreshToken> isAlreadyExist = refreshTokenRepository.findByUserId(userId);
isAlreadyExist.ifPresent(refreshToken -> refreshTokenRepository.delete(refreshToken));
RefreshToken refreshToken = new RefreshToken();
refreshToken.setUser(userRepository.findById(userId).get());
refreshToken.setExpirationDate(Instant.now().plusMillis(refreshTokenDurationMs));
refreshToken.setToken(UUID.randomUUID().toString());

View File

@@ -1,7 +1,7 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.service;
package com.hakimfauzi23.boilerplatespringsecurity.service;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.User;
import com.hakimfauzi23.boilerplatespringsecurity.data.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

View File

@@ -1,7 +1,7 @@
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.service;
package com.hakimfauzi23.boilerplatespringsecurity.service;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.User;
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.repository.UserRepository;
import com.hakimfauzi23.boilerplatespringsecurity.data.User;
import com.hakimfauzi23.boilerplatespringsecurity.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

View File

@@ -1,5 +1,5 @@
spring.datasource.url= jdbc:mysql://localhost:3306/testdb?useSSL=false
spring.datasource.username= root
spring.datasource.username=root
spring.datasource.password=
spring.jpa.hibernate.ddl-auto= update