diff --git a/README.md b/README.md index 657f73b..3c785cf 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ public AuthenticationManager authenticationManager(AuthenticationConfiguration a # TODO -- [ ] Implement regenerate refresh token +- [ ] Implement regenerate refresh token test code ### Done ✓ diff --git a/src/main/java/demo/api/auth/AuthController.java b/src/main/java/demo/api/auth/AuthController.java index cbef88c..56fe394 100644 --- a/src/main/java/demo/api/auth/AuthController.java +++ b/src/main/java/demo/api/auth/AuthController.java @@ -1,6 +1,7 @@ package demo.api.auth; import demo.api.auth.dtos.SignUpRes; +import demo.api.jwt.dtos.RegenerateTokenDto; import demo.api.jwt.dtos.TokenDto; import demo.api.auth.dtos.SignInReq; import demo.api.auth.dtos.SignUpReq; @@ -25,7 +26,12 @@ public class AuthController { } @PostMapping("/signIn") - public ResponseEntity signIn(@Validated SignInReq signInReq, HttpServletResponse res) { + public ResponseEntity signIn(@Validated SignInReq signInReq) { return authService.signIn(signInReq); } + + @PostMapping("/regenerateToken") + public ResponseEntity regenerateToken(@Validated RegenerateTokenDto refreshTokenDto) { + return authService.regenerateToken(refreshTokenDto); + } } diff --git a/src/main/java/demo/api/auth/AuthService.java b/src/main/java/demo/api/auth/AuthService.java index 6a2f5c4..7d5302c 100644 --- a/src/main/java/demo/api/auth/AuthService.java +++ b/src/main/java/demo/api/auth/AuthService.java @@ -1,6 +1,7 @@ package demo.api.auth; import demo.api.auth.dtos.SignUpRes; +import demo.api.jwt.dtos.RegenerateTokenDto; import demo.api.jwt.dtos.TokenDto; import demo.api.auth.dtos.SignInReq; import demo.api.auth.dtos.SignUpReq; @@ -20,4 +21,6 @@ public interface AuthService { * @return json web token */ ResponseEntity signIn(SignInReq signInReq); + + ResponseEntity regenerateToken(RegenerateTokenDto refreshTokenDto); } diff --git a/src/main/java/demo/api/auth/AuthServiceImpl.java b/src/main/java/demo/api/auth/AuthServiceImpl.java index 8d21ada..840c347 100644 --- a/src/main/java/demo/api/auth/AuthServiceImpl.java +++ b/src/main/java/demo/api/auth/AuthServiceImpl.java @@ -3,6 +3,7 @@ package demo.api.auth; import demo.api.auth.dtos.SignUpRes; import demo.api.exception.CustomException; import demo.api.jwt.JwtTokenProvider; +import demo.api.jwt.dtos.RegenerateTokenDto; import demo.api.jwt.dtos.TokenDto; import demo.api.user.domain.User; import demo.api.auth.dtos.SignInReq; @@ -84,7 +85,48 @@ public class AuthServiceImpl implements AuthService { return new ResponseEntity<>(tokenDto, httpHeaders, HttpStatus.OK); } catch (AuthenticationException e) { - throw new CustomException("Invalid credentials supplied", HttpStatus.UNPROCESSABLE_ENTITY); + throw new CustomException("Invalid credentials supplied", HttpStatus.BAD_REQUEST); + } + } + + @Override + public ResponseEntity regenerateToken(RegenerateTokenDto refreshTokenDto) { + String refresh_token = refreshTokenDto.getRefresh_token(); + try { + // 1. Refresh Token 검증 + if (!jwtTokenProvider.validateRefreshToken(refresh_token)) { + throw new CustomException("Invalid refresh token supplied", HttpStatus.BAD_REQUEST); + } + + // 2. Access Token 에서 User email 를 가져옵니다. + Authentication authentication = jwtTokenProvider.getAuthentication(refresh_token); + + // 3. Redis 에서 User email 을 기반으로 저장된 Refresh Token 값을 가져옵니다. + String refreshToken = (String)redisTemplate.opsForValue().get(authentication.getName()); + if(!refreshToken.equals(refresh_token)) { + throw new CustomException("Refresh Token doesn't match.", HttpStatus.BAD_REQUEST); + } + + // 4. 새로운 토큰 생성 + String new_refresh_token = jwtTokenProvider.generateRefreshToken(authentication); + TokenDto tokenDto = new TokenDto( + jwtTokenProvider.generateAccessToken(authentication), + new_refresh_token + ); + + // 5. RefreshToken Redis 업데이트 + redisTemplate.opsForValue().set( + authentication.getName(), + new_refresh_token, + refresh_token_expire_time, + TimeUnit.MILLISECONDS + ); + + HttpHeaders httpHeaders = new HttpHeaders(); + + return new ResponseEntity<>(tokenDto, httpHeaders, HttpStatus.OK); + } catch (AuthenticationException e) { + throw new CustomException("Invalid refresh token supplied", HttpStatus.BAD_REQUEST); } } } diff --git a/src/main/java/demo/api/jwt/dtos/RegenerateTokenDto.java b/src/main/java/demo/api/jwt/dtos/RegenerateTokenDto.java new file mode 100644 index 0000000..eea120f --- /dev/null +++ b/src/main/java/demo/api/jwt/dtos/RegenerateTokenDto.java @@ -0,0 +1,10 @@ +package demo.api.jwt.dtos; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class RegenerateTokenDto { + private String refresh_token; +}