From 4120b667dba0844a11a39cdc872df4071ae1d1f0 Mon Sep 17 00:00:00 2001 From: Park Dongkyu <86235780+dong99u@users.noreply.github.com> Date: Thu, 26 Sep 2024 11:47:31 +0900 Subject: [PATCH 1/2] =?UTF-8?q?Refactor:=20RequestParam=EC=9C=BC=EB=A1=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/petqa/api/AuthAPIController.java | 9 +++++---- .../java/com/petqa/service/user/UserCommandService.java | 2 +- .../com/petqa/service/user/UserCommandServiceImpl.java | 3 +-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/petqa/api/AuthAPIController.java b/src/main/java/com/petqa/api/AuthAPIController.java index 2f524af..9b60a6c 100644 --- a/src/main/java/com/petqa/api/AuthAPIController.java +++ b/src/main/java/com/petqa/api/AuthAPIController.java @@ -3,9 +3,11 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @@ -20,7 +22,6 @@ import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @RestController @@ -113,9 +114,9 @@ public ResponseEntity> logout(HttpServletRequest request, Ht return ResponseEntity.ok(ApiResponse.onSuccess("로그아웃 성공")); } - @PostMapping("/duplicate") - public ApiResponse checkDuplicate(@RequestBody @Valid UserRequestDTO.DuplicateCheckDTO duplicateCheckDTO) { - return ApiResponse.onSuccess(userCommandService.duplicateCheck(duplicateCheckDTO)); + @GetMapping("/duplicate") + public ApiResponse checkDuplicate(@RequestParam String username) { + return ApiResponse.onSuccess(userCommandService.duplicateCheck(username)); } } diff --git a/src/main/java/com/petqa/service/user/UserCommandService.java b/src/main/java/com/petqa/service/user/UserCommandService.java index 131bd87..f5b33a9 100644 --- a/src/main/java/com/petqa/service/user/UserCommandService.java +++ b/src/main/java/com/petqa/service/user/UserCommandService.java @@ -14,5 +14,5 @@ public interface UserCommandService { void logout(String refreshToken); - String duplicateCheck(UserRequestDTO.DuplicateCheckDTO duplicateCheckDTO); + String duplicateCheck(String username); } diff --git a/src/main/java/com/petqa/service/user/UserCommandServiceImpl.java b/src/main/java/com/petqa/service/user/UserCommandServiceImpl.java index 588e603..bb61fab 100644 --- a/src/main/java/com/petqa/service/user/UserCommandServiceImpl.java +++ b/src/main/java/com/petqa/service/user/UserCommandServiceImpl.java @@ -214,8 +214,7 @@ public void logout(String refreshToken) { } @Override - public String duplicateCheck(UserRequestDTO.DuplicateCheckDTO duplicateCheckDTO) { - String username = duplicateCheckDTO.getUsername(); + public String duplicateCheck(String username) { userRepository.findUserByUsername(username) .ifPresent(u -> { throw new UserHandler(ErrorStatus.USER_ALREADY_EXIST); From 81eb3a5a24f1068ec6801028e6516d8877dc824c Mon Sep 17 00:00:00 2001 From: Park Dongkyu <86235780+dong99u@users.noreply.github.com> Date: Sun, 6 Oct 2024 13:56:05 +0900 Subject: [PATCH 2/2] =?UTF-8?q?Refactor:=20reissue=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apiPayload/code/status/ErrorStatus.java | 113 +++++++++--------- .../service/user/UserCommandServiceImpl.java | 36 ++++-- 2 files changed, 84 insertions(+), 65 deletions(-) diff --git a/src/main/java/com/petqa/apiPayload/apiPayload/code/status/ErrorStatus.java b/src/main/java/com/petqa/apiPayload/apiPayload/code/status/ErrorStatus.java index 91fac47..fe4f3cd 100644 --- a/src/main/java/com/petqa/apiPayload/apiPayload/code/status/ErrorStatus.java +++ b/src/main/java/com/petqa/apiPayload/apiPayload/code/status/ErrorStatus.java @@ -1,73 +1,76 @@ package com.petqa.apiPayload.apiPayload.code.status; +import org.springframework.http.HttpStatus; + import com.petqa.apiPayload.apiPayload.code.BaseErrorCode; import com.petqa.apiPayload.apiPayload.code.ErrorReasonDTO; + import lombok.AllArgsConstructor; import lombok.Getter; -import org.springframework.http.HttpStatus; @Getter @AllArgsConstructor public enum ErrorStatus implements BaseErrorCode { - // 가장 일반적인 응답 - INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "COMMON500", "서버 에러, 관리자에게 문의 바랍니다."), - BAD_REQUEST(HttpStatus.BAD_REQUEST, "COMMON400", "잘못된 요청입니다."), - UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "COMMON401", "인증이 필요합니다."), - FORBIDDEN(HttpStatus.FORBIDDEN, "COMMON403", "금지된 요청입니다."), + // 가장 일반적인 응답 + INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "COMMON500", "서버 에러, 관리자에게 문의 바랍니다."), + BAD_REQUEST(HttpStatus.BAD_REQUEST, "COMMON400", "잘못된 요청입니다."), + UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "COMMON401", "인증이 필요합니다."), + FORBIDDEN(HttpStatus.FORBIDDEN, "COMMON403", "금지된 요청입니다."), - // 유저 관련 에러 - USER_NOT_FOUND(HttpStatus.BAD_REQUEST, "USER4001", "유저를 찾을 수 없습니다."), - USER_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "USER4002", - "이미 존재하는 유저입니다."), - USER_NOT_MATCH(HttpStatus.BAD_REQUEST, "USER4003", "유저 정보가 일치하지 않습니다."), - USER_NOT_AUTHORIZED(HttpStatus.BAD_REQUEST, "USER4004", "유저 권한이 없습니다."), - USER_NOT_VALID(HttpStatus.BAD_REQUEST, "USER4005", "유저 정보가 유효하지 않습니다."), - USER_NOT_ACTIVE(HttpStatus.BAD_REQUEST, "USER4006", "유저가 비활성화 되었습니다."), - USER_NOT_LOGIN(HttpStatus.BAD_REQUEST, "USER4007", "로그인이 필요합니다."), - USER_NOT_EMAIL(HttpStatus.BAD_REQUEST, "USER4008", "이메일이 없습니다."), - USER_NOT_PASSWORD(HttpStatus.BAD_REQUEST, "USER4009", - "비밀번호가 없습니다."), - USER_NOT_NAME(HttpStatus.BAD_REQUEST, "USER4010", "이름이 없습니다."), - USER_NOT_PHONE(HttpStatus.BAD_REQUEST, "USER4011", "전화번호가 없습니다."), + // 유저 관련 에러 + USER_NOT_FOUND(HttpStatus.BAD_REQUEST, "USER4001", "유저를 찾을 수 없습니다."), + USER_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "USER4002", + "이미 존재하는 유저입니다."), + USER_NOT_MATCH(HttpStatus.BAD_REQUEST, "USER4003", "유저 정보가 일치하지 않습니다."), + USER_NOT_AUTHORIZED(HttpStatus.BAD_REQUEST, "USER4004", "유저 권한이 없습니다."), + USER_NOT_VALID(HttpStatus.BAD_REQUEST, "USER4005", "유저 정보가 유효하지 않습니다."), + USER_NOT_ACTIVE(HttpStatus.BAD_REQUEST, "USER4006", "유저가 비활성화 되었습니다."), + USER_NOT_LOGIN(HttpStatus.BAD_REQUEST, "USER4007", "로그인이 필요합니다."), + USER_NOT_EMAIL(HttpStatus.BAD_REQUEST, "USER4008", "이메일이 없습니다."), + USER_NOT_PASSWORD(HttpStatus.BAD_REQUEST, "USER4009", + "비밀번호가 없습니다."), + USER_NOT_NAME(HttpStatus.BAD_REQUEST, "USER4010", "이름이 없습니다."), + USER_NOT_PHONE(HttpStatus.BAD_REQUEST, "USER4011", "전화번호가 없습니다."), + USERNAME_IS_NULL(HttpStatus.BAD_REQUEST, "USER4012", "유저 이름이 없습니다."), - // Token 관련 에러 - REFRESH_TOKEN_NOT_FOUND(HttpStatus.BAD_REQUEST, "REFRESH4001", "리프레시 토큰이 없습니다."), - REFRESH_TOKEN_EXPIRED(HttpStatus.BAD_REQUEST, "REFRESH4002", "리프레시 토큰이 만료되었습니다."), - ACCESS_TOKEN_EXPIRED(HttpStatus.BAD_REQUEST, "ACCESS4001", "액세스 토큰이 만료되었습니다."), - INVALID_TOKEN(HttpStatus.BAD_REQUEST, "TOKEN4001", "유효하지 않은 토큰입니다."), + // Token 관련 에러 + REFRESH_TOKEN_NOT_FOUND(HttpStatus.BAD_REQUEST, "REFRESH4001", "리프레시 토큰이 없습니다."), + REFRESH_TOKEN_EXPIRED(HttpStatus.BAD_REQUEST, "REFRESH4002", "리프레시 토큰이 만료되었습니다."), + ACCESS_TOKEN_EXPIRED(HttpStatus.BAD_REQUEST, "ACCESS4001", "액세스 토큰이 만료되었습니다."), + INVALID_TOKEN(HttpStatus.BAD_REQUEST, "TOKEN4001", "유효하지 않은 토큰입니다."), - FILE_UPLOAD_FAILED(HttpStatus.BAD_REQUEST, "FILE4001", "파일 업로드에 실패했습니다."), + FILE_UPLOAD_FAILED(HttpStatus.BAD_REQUEST, "FILE4001", "파일 업로드에 실패했습니다."), - // 커뮤니티 관련 에러 - POST_NOT_EXIST(HttpStatus.BAD_REQUEST, "COMMUNITY3001", "존재하지 않는 게시글 입니다."), - COMMENT_NOT_EXIST(HttpStatus.BAD_REQUEST, "COMMUNITY3001", "존재하지 않는 댓글 입니다."), - VOTE_NOT_EXIST(HttpStatus.BAD_REQUEST, "COMMUNITY3002", "존재하지 않는 투표입니다."), - VOTE_NOT_MULTI(HttpStatus.BAD_REQUEST, "COMMUNITY3003", "복수 선택이 불가능한 투표입니다."), - VOTE_AFTER_END(HttpStatus.BAD_REQUEST, "COMMUNITY3004", "투표기간이 끝났습니다."), - VOTE_COUNT_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "COMMUNITY3005", "이미 투표했습니다."), - VOTE_ITEM_NOT_EXIST(HttpStatus.BAD_REQUEST, "COMMUNITY3006", "존재하지 않는 투표 선택지입니다.") - ; + // 커뮤니티 관련 에러 + POST_NOT_EXIST(HttpStatus.BAD_REQUEST, "COMMUNITY3001", "존재하지 않는 게시글 입니다."), + COMMENT_NOT_EXIST(HttpStatus.BAD_REQUEST, "COMMUNITY3001", "존재하지 않는 댓글 입니다."), + VOTE_NOT_EXIST(HttpStatus.BAD_REQUEST, "COMMUNITY3002", "존재하지 않는 투표입니다."), + VOTE_NOT_MULTI(HttpStatus.BAD_REQUEST, "COMMUNITY3003", "복수 선택이 불가능한 투표입니다."), + VOTE_AFTER_END(HttpStatus.BAD_REQUEST, "COMMUNITY3004", "투표기간이 끝났습니다."), + VOTE_COUNT_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "COMMUNITY3005", "이미 투표했습니다."), + VOTE_ITEM_NOT_EXIST(HttpStatus.BAD_REQUEST, "COMMUNITY3006", "존재하지 않는 투표 선택지입니다."), + ; - private final HttpStatus httpStatus; - private final String code; - private final String message; + private final HttpStatus httpStatus; + private final String code; + private final String message; - @Override - public ErrorReasonDTO getReason() { - return ErrorReasonDTO.builder() - .message(message) - .code(code) - .isSuccess(false) - .build(); - } + @Override + public ErrorReasonDTO getReason() { + return ErrorReasonDTO.builder() + .message(message) + .code(code) + .isSuccess(false) + .build(); + } - @Override - public ErrorReasonDTO getReasonHttpStatus() { - return ErrorReasonDTO.builder() - .message(message) - .code(code) - .isSuccess(false) - .httpStatus(httpStatus) - .build(); - } + @Override + public ErrorReasonDTO getReasonHttpStatus() { + return ErrorReasonDTO.builder() + .message(message) + .code(code) + .isSuccess(false) + .httpStatus(httpStatus) + .build(); + } } diff --git a/src/main/java/com/petqa/service/user/UserCommandServiceImpl.java b/src/main/java/com/petqa/service/user/UserCommandServiceImpl.java index bb61fab..7f9d717 100644 --- a/src/main/java/com/petqa/service/user/UserCommandServiceImpl.java +++ b/src/main/java/com/petqa/service/user/UserCommandServiceImpl.java @@ -25,6 +25,8 @@ import com.petqa.service.refresh.RefreshCommandService; import com.petqa.service.s3Bucket.S3Service; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.JwtException; import lombok.RequiredArgsConstructor; @Service @@ -161,28 +163,38 @@ public AuthResponseDTO.ReissueResponseDTO reissue(String refreshToken) { if (refreshToken == null) { throw new TokenHandler(ErrorStatus.INVALID_TOKEN); } - try { - jwtUtil.isExpired(refreshToken); - } catch (Exception e) { + // Check if the token is expired + if (jwtUtil.isExpired(refreshToken)) { + throw new TokenHandler(ErrorStatus.REFRESH_TOKEN_EXPIRED); + } + } catch (ExpiredJwtException e) { + // Token has expired throw new TokenHandler(ErrorStatus.REFRESH_TOKEN_EXPIRED); + } catch (JwtException e) { + // Token is invalid for other reasons + throw new TokenHandler(ErrorStatus.INVALID_TOKEN); + } catch (Exception e) { + // Handle any other exceptions + throw new TokenHandler(ErrorStatus.INVALID_TOKEN); } + // Extract claims safely String category = jwtUtil.getCategory(refreshToken); - - if (!category.equals("refresh")) { + if (!"refresh".equals(category)) { throw new TokenHandler(ErrorStatus.INVALID_TOKEN); } String socialId = jwtUtil.getSocialId(refreshToken); String username = jwtUtil.getUsername(refreshToken); - + // 기존 리프레시 토큰 삭제 refreshRepository.deleteByRefresh(refreshToken); - refreshCommandService.addRefresh(username, socialId, refreshToken, refreshTokenExpiration); - - String newAccessToken = jwtUtil.createJwt("access", socialId, username, accessTokenExpiration); + // 새로운 리프레시 토큰 생성 String newRefreshToken = jwtUtil.createJwt("refresh", socialId, username, refreshTokenExpiration); - + // 새로운 리프레시 토큰 저장 + refreshCommandService.addRefresh(username, socialId, newRefreshToken, refreshTokenExpiration); + // 새로운 액세스 토큰 생성 + String newAccessToken = jwtUtil.createJwt("access", socialId, username, accessTokenExpiration); return AuthResponseDTO.ReissueResponseDTO.builder() .accessToken(newAccessToken) .refreshToken(newRefreshToken) @@ -215,6 +227,10 @@ public void logout(String refreshToken) { @Override public String duplicateCheck(String username) { + if (username == null || username.isEmpty()) { + throw new UserHandler(ErrorStatus.USERNAME_IS_NULL); + } + userRepository.findUserByUsername(username) .ifPresent(u -> { throw new UserHandler(ErrorStatus.USER_ALREADY_EXIST);