diff --git a/src/main/java/com/kamco/cd/kamcoback/members/AuthController.java b/src/main/java/com/kamco/cd/kamcoback/members/AuthController.java index f21a02c8..ffe785e3 100644 --- a/src/main/java/com/kamco/cd/kamcoback/members/AuthController.java +++ b/src/main/java/com/kamco/cd/kamcoback/members/AuthController.java @@ -55,55 +55,55 @@ public class AuthController { @Operation(summary = "로그인", description = "사번으로 로그인하여 액세스/리프레시 토큰을 발급.") @ApiResponses({ @ApiResponse( - responseCode = "200", - description = "로그인 성공", - content = @Content(schema = @Schema(implementation = TokenResponse.class))), + responseCode = "200", + description = "로그인 성공", + content = @Content(schema = @Schema(implementation = TokenResponse.class))), @ApiResponse( - responseCode = "401", - description = "로그인 실패 (아이디/비밀번호 오류, 계정잠금 등)", - content = - @Content( - schema = @Schema(implementation = ErrorResponse.class), - examples = { - @ExampleObject( - name = "아이디 입력 오류", - description = "존재하지 않는 아이디", - value = - """ + responseCode = "401", + description = "로그인 실패 (아이디/비밀번호 오류, 계정잠금 등)", + content = + @Content( + schema = @Schema(implementation = ErrorResponse.class), + examples = { + @ExampleObject( + name = "아이디 입력 오류", + description = "존재하지 않는 아이디", + value = + """ { "code": "LOGIN_ID_NOT_FOUND", "message": "아이디를 잘못 입력하셨습니다." } """), - @ExampleObject( - name = "비밀번호 입력 오류 (4회 이하)", - description = "아이디는 정상, 비밀번호를 여러 번 틀린 경우", - value = - """ + @ExampleObject( + name = "비밀번호 입력 오류 (4회 이하)", + description = "아이디는 정상, 비밀번호를 여러 번 틀린 경우", + value = + """ { "code": "LOGIN_PASSWORD_MISMATCH", "message": "비밀번호를 잘못 입력하셨습니다." } """), - @ExampleObject( - name = "비밀번호 오류 횟수 초과", - description = "비밀번호 5회 이상 오류로 계정 잠김", - value = - """ + @ExampleObject( + name = "비밀번호 오류 횟수 초과", + description = "비밀번호 5회 이상 오류로 계정 잠김", + value = + """ { "code": "LOGIN_PASSWORD_EXCEEDED", "message": "비밀번호 오류 횟수를 초과하여 이용하실 수 없습니다. 로그인 오류에 대해 관리자에게 문의하시기 바랍니다." } """) - })) + })) }) public ApiResponseDto signin( - @io.swagger.v3.oas.annotations.parameters.RequestBody( - description = "로그인 요청 정보", - required = true) - @RequestBody - SignInRequest request, - HttpServletResponse response) { + @io.swagger.v3.oas.annotations.parameters.RequestBody( + description = "로그인 요청 정보", + required = true) + @RequestBody + SignInRequest request, + HttpServletResponse response) { // 사용자 상태 조회 String status = authService.getUserStatus(request); @@ -111,14 +111,8 @@ public class AuthController { MembersDto.Member member = new MembersDto.Member(); authentication = - authenticationManager.authenticate( - new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword())); - - // PENDING 비활성 상태(새로운 패스워드 입력 해야함) - if (StatusType.PENDING.getId().equals(status)) { - member.setEmployeeNo(request.getUsername()); - return ApiResponseDto.ok(new TokenResponse(status, null, null, member)); - } + authenticationManager.authenticate( + new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword())); String username = authentication.getName(); // UserDetailsService 에서 사용한 username @@ -127,17 +121,17 @@ public class AuthController { // Redis에 RefreshToken 저장 (TTL = 7일) refreshTokenService.save( - username, refreshToken, jwtTokenProvider.getRefreshTokenValidityInMs()); + username, refreshToken, jwtTokenProvider.getRefreshTokenValidityInMs()); // HttpOnly + Secure 쿠키에 RefreshToken 저장 ResponseCookie cookie = - ResponseCookie.from(refreshCookieName, refreshToken) - .httpOnly(true) - .secure(refreshCookieSecure) - .path("/") - .maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs())) - .sameSite("Strict") - .build(); + ResponseCookie.from(refreshCookieName, refreshToken) + .httpOnly(true) + .secure(refreshCookieSecure) + .path("/") + .maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs())) + .sameSite("Strict") + .build(); response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString()); @@ -146,6 +140,12 @@ public class AuthController { member.setName(user.getMember().getName()); member.setEmployeeNo(user.getMember().getEmployeeNo()); + // PENDING 비활성 상태(새로운 패스워드 입력 해야함) + if (StatusType.PENDING.getId().equals(status)) { + member.setEmployeeNo(request.getUsername()); + return ApiResponseDto.ok(new TokenResponse(status, accessToken, refreshToken, member)); + } + // 인증 성공 로그인 시간 저장 authService.saveLogin(UUID.fromString(username)); @@ -156,16 +156,16 @@ public class AuthController { @Operation(summary = "토큰 재발급", description = "리프레시 토큰으로 새로운 액세스/리프레시 토큰을 재발급합니다.") @ApiResponses({ @ApiResponse( - responseCode = "200", - description = "재발급 성공", - content = @Content(schema = @Schema(implementation = TokenResponse.class))), + responseCode = "200", + description = "재발급 성공", + content = @Content(schema = @Schema(implementation = TokenResponse.class))), @ApiResponse( - responseCode = "403", - description = "만료되었거나 유효하지 않은 리프레시 토큰", - content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + responseCode = "403", + description = "만료되었거나 유효하지 않은 리프레시 토큰", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) public ResponseEntity refresh(String refreshToken, HttpServletResponse response) - throws AccessDeniedException { + throws AccessDeniedException { if (refreshToken == null || !jwtTokenProvider.isValidToken(refreshToken)) { throw new AccessDeniedException("만료되었거나 유효하지 않은 리프레시 토큰 입니다."); } @@ -182,17 +182,17 @@ public class AuthController { // Redis 갱신 refreshTokenService.save( - username, newRefreshToken, jwtTokenProvider.getRefreshTokenValidityInMs()); + username, newRefreshToken, jwtTokenProvider.getRefreshTokenValidityInMs()); // 쿠키 갱신 ResponseCookie cookie = - ResponseCookie.from(refreshCookieName, newRefreshToken) - .httpOnly(true) - .secure(refreshCookieSecure) - .path("/") - .maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs())) - .sameSite("Strict") - .build(); + ResponseCookie.from(refreshCookieName, newRefreshToken) + .httpOnly(true) + .secure(refreshCookieSecure) + .path("/") + .maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs())) + .sameSite("Strict") + .build(); response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString()); MembersDto.Member member = new MembersDto.Member(); @@ -203,12 +203,12 @@ public class AuthController { @Operation(summary = "로그아웃", description = "현재 사용자의 토큰을 무효화(리프레시 토큰 삭제)합니다.") @ApiResponses({ @ApiResponse( - responseCode = "200", - description = "로그아웃 성공", - content = @Content(schema = @Schema(implementation = Void.class))) + responseCode = "200", + description = "로그아웃 성공", + content = @Content(schema = @Schema(implementation = Void.class))) }) public ApiResponseDto> logout( - Authentication authentication, HttpServletResponse response) { + Authentication authentication, HttpServletResponse response) { if (authentication != null) { String username = authentication.getName(); // Redis에서 RefreshToken 삭제 @@ -217,13 +217,13 @@ public class AuthController { // 쿠키 삭제 (Max-Age=0) ResponseCookie cookie = - ResponseCookie.from(refreshCookieName, "") - .httpOnly(true) - .secure(refreshCookieSecure) - .path("/") - .maxAge(0) - .sameSite("Strict") - .build(); + ResponseCookie.from(refreshCookieName, "") + .httpOnly(true) + .secure(refreshCookieSecure) + .path("/") + .maxAge(0) + .sameSite("Strict") + .build(); response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString()); return ApiResponseDto.createOK(ResponseEntity.noContent().build());