From 0ac4c743ed6470a940179bbff73c6ccdb7728b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9A=A9=EC=88=98?= Date: Tue, 24 Sep 2024 12:05:56 +0900 Subject: [PATCH] =?UTF-8?q?Feat:=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=ED=95=B8=EB=93=A4=EB=9F=AC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/controller/AuthController.java | 7 ++-- .../auth/handler/CustomLogoutHandler.java | 38 +++++++++++++++++++ .../domain/auth/service/AuthService.java | 22 +++++++++-- .../global/config/SecurityConfig.java | 1 - 4 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 backend/src/main/java/com/worlabel/domain/auth/handler/CustomLogoutHandler.java diff --git a/backend/src/main/java/com/worlabel/domain/auth/controller/AuthController.java b/backend/src/main/java/com/worlabel/domain/auth/controller/AuthController.java index 13437ec..ac9ef9b 100644 --- a/backend/src/main/java/com/worlabel/domain/auth/controller/AuthController.java +++ b/backend/src/main/java/com/worlabel/domain/auth/controller/AuthController.java @@ -12,6 +12,7 @@ import com.worlabel.global.config.swagger.SwaggerApiError; import com.worlabel.global.config.swagger.SwaggerApiSuccess; import com.worlabel.global.exception.CustomException; import com.worlabel.global.exception.ErrorCode; +import com.worlabel.global.service.FcmService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.Cookie; @@ -65,7 +66,7 @@ public class AuthController { @SwaggerApiSuccess(description = "Return Member Info") @SwaggerApiError({ErrorCode.INVALID_TOKEN, ErrorCode.INVALID_REFRESH_TOKEN, ErrorCode.USER_NOT_FOUND}) @GetMapping("/profile") - public MemberResponse getMemberInfo(@CurrentUser Integer currentMember){ + public MemberResponse getMemberInfo(@CurrentUser final Integer currentMember){ return memberService.getMemberId(currentMember); } @@ -73,8 +74,8 @@ public class AuthController { @SwaggerApiSuccess(description = "Redis에 FCM 토큰이 저장됨") @SwaggerApiError({ErrorCode.INVALID_TOKEN, ErrorCode.INVALID_REFRESH_TOKEN, ErrorCode.USER_NOT_FOUND}) @PostMapping("/fcm") - public void saveFcmToken(@CurrentUser Integer currentMember, @RequestBody final FcmTokenRequest tokenRequest){ - + public void saveFcmToken(@CurrentUser final Integer currentMember, @RequestBody final FcmTokenRequest tokenRequest){ + authService.saveFcmToken(currentMember, tokenRequest.getToken()); } private static String parseRefreshCookie(HttpServletRequest request) { diff --git a/backend/src/main/java/com/worlabel/domain/auth/handler/CustomLogoutHandler.java b/backend/src/main/java/com/worlabel/domain/auth/handler/CustomLogoutHandler.java new file mode 100644 index 0000000..6863f46 --- /dev/null +++ b/backend/src/main/java/com/worlabel/domain/auth/handler/CustomLogoutHandler.java @@ -0,0 +1,38 @@ +package com.worlabel.domain.auth.handler; + +import com.worlabel.domain.auth.service.AuthService; +import com.worlabel.domain.auth.service.JwtTokenService; +import com.worlabel.global.exception.CustomException; +import com.worlabel.global.exception.ErrorCode; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.logout.LogoutHandler; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@RequiredArgsConstructor +public class CustomLogoutHandler implements LogoutHandler { + + private AuthService authService; + private JwtTokenService jwtTokenService; + + @Override + public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { + String token = request.getHeader("Authorization"); + try { + String refreshedToken = token.substring(7); + int memberId = jwtTokenService.parseId(refreshedToken); + + authService.deleteRefreshToken(memberId); + authService.deleteFcmToken(memberId); + + log.debug("로그아웃된 사용자의 토큰이 삭제 됨 {}", memberId); + } catch (Exception e) { + throw new CustomException(ErrorCode.INVALID_REFRESH_TOKEN); + } + } +} diff --git a/backend/src/main/java/com/worlabel/domain/auth/service/AuthService.java b/backend/src/main/java/com/worlabel/domain/auth/service/AuthService.java index 3b903f6..c5ce860 100644 --- a/backend/src/main/java/com/worlabel/domain/auth/service/AuthService.java +++ b/backend/src/main/java/com/worlabel/domain/auth/service/AuthService.java @@ -2,6 +2,7 @@ package com.worlabel.domain.auth.service; import com.worlabel.domain.auth.entity.dto.JwtToken; import com.worlabel.domain.auth.repository.AuthCacheRepository; +import com.worlabel.domain.auth.repository.FcmRepository; import com.worlabel.global.exception.CustomException; import com.worlabel.global.exception.ErrorCode; import lombok.RequiredArgsConstructor; @@ -15,9 +16,10 @@ import java.util.Objects; @Service @RequiredArgsConstructor public class AuthService { - - private final JwtTokenService jwtTokenService; + private final AuthCacheRepository authCacheRepository; + private final JwtTokenService jwtTokenService; + private final FcmRepository fcmRepository;; /** * JWT 토큰 재발급 @@ -34,7 +36,19 @@ public class AuthService { /** * 레디에 리프레시 토큰 저장 */ - public void saveRefreshToken(int id, String refreshToken,Long expiredTime) { - authCacheRepository.save(id, refreshToken, expiredTime); + public void saveRefreshToken(int memberId, String refreshToken,Long expiredTime) { + authCacheRepository.save(memberId, refreshToken, expiredTime); + } + + public void deleteRefreshToken(int memberId) { + authCacheRepository.delete(memberId); + } + + public void saveFcmToken(int memberId, String fcmToken) { + fcmRepository.save(memberId, fcmToken); + } + + public void deleteFcmToken(int memberId) { + fcmRepository.delete(memberId); } } diff --git a/backend/src/main/java/com/worlabel/global/config/SecurityConfig.java b/backend/src/main/java/com/worlabel/global/config/SecurityConfig.java index c5eeb15..423e964 100644 --- a/backend/src/main/java/com/worlabel/global/config/SecurityConfig.java +++ b/backend/src/main/java/com/worlabel/global/config/SecurityConfig.java @@ -82,7 +82,6 @@ public class SecurityConfig { .successHandler(oAuth2SuccessHandler) ); - // JWT 필터 추가 http .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);