From 913e2c38b490dd670b28a6eb938977ac8b984427 Mon Sep 17 00:00:00 2001 From: SSung023 Date: Thu, 1 May 2025 11:58:16 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83=20API=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 로그아웃 API 개발 `POST /api/logout?nickname={nickname}` - redis에서 refresh-token 정보 삭제 및 Cookie에서 refresh token 삭제 --- .../core/security/controller/AuthApi.java | 4 ++++ .../security/controller/AuthController.java | 8 ++++++++ .../herewe/core/security/facade/AuthFacade.java | 2 ++ .../core/security/facade/DefaultAuthFacade.java | 17 +++++++++++++++++ 4 files changed, 31 insertions(+) diff --git a/src/main/java/com/genius/herewe/core/security/controller/AuthApi.java b/src/main/java/com/genius/herewe/core/security/controller/AuthApi.java index 10abee0..17295dd 100644 --- a/src/main/java/com/genius/herewe/core/security/controller/AuthApi.java +++ b/src/main/java/com/genius/herewe/core/security/controller/AuthApi.java @@ -2,7 +2,9 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import com.genius.herewe.core.global.response.CommonResponse; import com.genius.herewe.core.global.response.ExceptionResponse; import com.genius.herewe.core.global.response.SingleResponse; import com.genius.herewe.core.security.dto.AuthRequest; @@ -111,4 +113,6 @@ SingleResponse authorize(HttpServletResponse response, ) }) SingleResponse reissueToken(HttpServletRequest request, HttpServletResponse response); + + CommonResponse logout(HttpServletResponse response, @RequestParam String nickname); } diff --git a/src/main/java/com/genius/herewe/core/security/controller/AuthController.java b/src/main/java/com/genius/herewe/core/security/controller/AuthController.java index 4f60f7c..db316be 100644 --- a/src/main/java/com/genius/herewe/core/security/controller/AuthController.java +++ b/src/main/java/com/genius/herewe/core/security/controller/AuthController.java @@ -5,8 +5,10 @@ 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.RestController; +import com.genius.herewe.core.global.response.CommonResponse; import com.genius.herewe.core.global.response.SingleResponse; import com.genius.herewe.core.security.dto.AuthRequest; import com.genius.herewe.core.security.dto.AuthResponse; @@ -39,6 +41,12 @@ public SingleResponse reissueToken(HttpServletRequest request, Htt return new SingleResponse<>(HttpStatus.OK, authResponse); } + @PostMapping("/auth/logout") + public CommonResponse logout(HttpServletResponse response, @RequestParam String nickname) { + authFacade.logout(response, nickname); + return CommonResponse.ok(); + } + @GetMapping("/auth/health-check") public String healthCheck() { return "health check OK"; diff --git a/src/main/java/com/genius/herewe/core/security/facade/AuthFacade.java b/src/main/java/com/genius/herewe/core/security/facade/AuthFacade.java index 32f5cc6..a7e1e34 100644 --- a/src/main/java/com/genius/herewe/core/security/facade/AuthFacade.java +++ b/src/main/java/com/genius/herewe/core/security/facade/AuthFacade.java @@ -9,4 +9,6 @@ public interface AuthFacade { Long authorize(HttpServletResponse response, AuthRequest authRequest); Long reissueToken(HttpServletRequest request, HttpServletResponse response); + + void logout(HttpServletResponse response, String nickname); } diff --git a/src/main/java/com/genius/herewe/core/security/facade/DefaultAuthFacade.java b/src/main/java/com/genius/herewe/core/security/facade/DefaultAuthFacade.java index e74bfb6..dde0d30 100644 --- a/src/main/java/com/genius/herewe/core/security/facade/DefaultAuthFacade.java +++ b/src/main/java/com/genius/herewe/core/security/facade/DefaultAuthFacade.java @@ -1,6 +1,7 @@ package com.genius.herewe.core.security.facade; import static com.genius.herewe.core.global.exception.ErrorCode.*; +import static com.genius.herewe.core.security.constants.JwtRule.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -9,9 +10,11 @@ import com.genius.herewe.core.security.dto.AuthRequest; import com.genius.herewe.core.security.service.JwtManager; import com.genius.herewe.core.security.service.token.AuthTokenService; +import com.genius.herewe.core.security.service.token.RefreshTokenService; import com.genius.herewe.core.user.domain.User; import com.genius.herewe.core.user.service.UserService; +import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; @@ -23,6 +26,7 @@ public class DefaultAuthFacade implements AuthFacade { private final JwtManager jwtManager; private final UserService userService; private final AuthTokenService authTokenService; + private final RefreshTokenService refreshTokenService; @Transactional public Long authorize(HttpServletResponse response, AuthRequest authRequest) { @@ -55,4 +59,17 @@ public Long reissueToken(HttpServletRequest request, HttpServletResponse respons return user.getId(); } + + @Override + public void logout(HttpServletResponse response, String nickname) { + User user = userService.findByNickname(nickname) + .orElseThrow(() -> new BusinessException(MEMBER_NOT_FOUND)); + + Cookie cookie = new Cookie(REFRESH_PREFIX.getValue(), null); + cookie.setMaxAge(0); + cookie.setPath("/"); + response.addCookie(cookie); + + refreshTokenService.delete(user.getId()); + } } From 33dd255245c98182f355c8fd8ead774224391633 Mon Sep 17 00:00:00 2001 From: SSung023 Date: Thu, 1 May 2025 12:33:19 +0900 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20swagger=20docs=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /api/auth/logout에 대해 swagger docs 작성 --- .../core/security/controller/AuthApi.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/main/java/com/genius/herewe/core/security/controller/AuthApi.java b/src/main/java/com/genius/herewe/core/security/controller/AuthApi.java index 17295dd..3735824 100644 --- a/src/main/java/com/genius/herewe/core/security/controller/AuthApi.java +++ b/src/main/java/com/genius/herewe/core/security/controller/AuthApi.java @@ -114,5 +114,34 @@ SingleResponse authorize(HttpServletResponse response, }) SingleResponse reissueToken(HttpServletRequest request, HttpServletResponse response); + @Operation(summary = "로그아웃 API", description = "로그아웃 처리를 하는 API로서, redis & cookie에서 토큰 정보 삭제") + @ApiResponses({ + @ApiResponse( + responseCode = "200", + description = "로그아웃 처리 성공" + ), + @ApiResponse( + responseCode = "404", + description = "해당 닉네임을 사용하고 있는 사용자를 찾지 못한 경우", + content = @Content( + schema = @Schema(implementation = ExceptionResponse.class), + examples = { + @ExampleObject( + name = "해당 닉네임을 사용하고 있는 사용자를 찾지 못한 경우", + value = """ + { + "resultCode": "404", + "code": "MEMBER_NOT_FOUND", + "message": "사용자를 찾을 수 없습니다." + } + """ + ) + } + ) + ) + }) CommonResponse logout(HttpServletResponse response, @RequestParam String nickname); + + @Operation(summary = "health check 전용 API", description = "서버가 제대로 동작하는지 확인하는 API") + String healthCheck(); }