From 9167dbfc8d706861860fd7e1cffd1e60a322f17b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9C=A4?= Date: Mon, 13 Jan 2025 15:38:55 +0900 Subject: [PATCH 1/9] =?UTF-8?q?[refactor]=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=8B=A4=ED=8C=A8=20=EB=A1=9C=EA=B9=85=20=EB=A0=88=EB=B2=A8=20?= =?UTF-8?q?=EC=9E=AC=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../security/handler/CustomAuthenticationFailHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/favoriteplace/global/security/handler/CustomAuthenticationFailHandler.java b/src/main/java/com/favoriteplace/global/security/handler/CustomAuthenticationFailHandler.java index b002fec4..6eb80b78 100644 --- a/src/main/java/com/favoriteplace/global/security/handler/CustomAuthenticationFailHandler.java +++ b/src/main/java/com/favoriteplace/global/security/handler/CustomAuthenticationFailHandler.java @@ -17,7 +17,7 @@ public class CustomAuthenticationFailHandler implements AuthenticationFailureHan @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { - log.info("로그인 실패 | message : {}" , exception.getMessage()); + log.warn("로그인 실패 | message : {}" , exception.getMessage()); String errorMessage = "login failed"; response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); From f1456e7c53cf2705a195fdd7b82a632d40a198b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9C=A4?= Date: Mon, 13 Jan 2025 16:01:21 +0900 Subject: [PATCH 2/9] =?UTF-8?q?[refactor]=20TokenInfoDto=20record=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=EC=9C=BC=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존에 MemberDto의 내부 정적 클래스로 존재하던 TokenDto를 record로 분리했습니다. --- logs/logfile.log | 50 +++++++++---------- .../app/controller/MemberController.java | 6 +-- .../PilgrimageSocketController.java | 3 +- .../app/dto/member/MemberDto.java | 16 ++---- .../app/dto/member/TokenInfoDto.java | 14 ++++++ .../app/service/MemberService.java | 15 +++--- 6 files changed, 54 insertions(+), 50 deletions(-) create mode 100644 src/main/java/com/favoriteplace/app/dto/member/TokenInfoDto.java diff --git a/logs/logfile.log b/logs/logfile.log index ee39d0ea..a79196c5 100644 --- a/logs/logfile.log +++ b/logs/logfile.log @@ -49,7 +49,7 @@ 2024-10-01T19:13:40.466+09:00 INFO 44119 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.favoriteplace.app.repository.VisitedPilgrimageRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository 2024-10-01T19:13:40.467+09:00 INFO 44119 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 36 ms. Found 0 Redis repository interfaces. 2024-10-01T19:13:40.859+09:00 INFO 44119 --- [restartedMain] o.s.c.c.s.GenericScope : BeanFactory id=f56eb2bf-d308-3960-b992-e76803ef57a9 -2024-10-01T19:13:40.918+09:00 INFO 44119 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.security.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2024-10-01T19:13:40.918+09:00 INFO 44119 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.auth.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2024-10-01T19:13:41.867+09:00 INFO 44119 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2024-10-01T19:13:41.877+09:00 INFO 44119 --- [restartedMain] o.a.c.h.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-8080"] 2024-10-01T19:13:41.880+09:00 INFO 44119 --- [restartedMain] o.a.c.c.StandardService : Starting service [Tomcat] @@ -88,8 +88,8 @@ 2024-10-01T19:13:47.246+09:00 WARN 44119 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.BlockRepository 2024-10-01T19:13:47.263+09:00 WARN 44119 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.CompleteRallyRepository 2024-10-01T19:13:47.299+09:00 WARN 44119 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.AddressRepository -2024-10-01T19:13:47.372+09:00 WARN 44119 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.global.security.config.SecurityConfig -2024-10-01T19:13:48.810+09:00 INFO 44119 --- [restartedMain] o.s.s.w.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@29b0a200, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@36ee9865, org.springframework.security.web.context.SecurityContextHolderFilter@36dcfa87, org.springframework.security.web.header.HeaderWriterFilter@4577a1fa, org.springframework.web.filter.CorsFilter@3fcf0fd2, org.springframework.security.web.authentication.logout.LogoutFilter@206ab993, com.favoriteplace.global.security.filter.ExceptionHandlerFilter@a32c846, com.favoriteplace.global.security.filter.JwtAuthenticationFilter@31e98479, com.favoriteplace.global.security.filter.LoginFilter@1de580e6, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5b7244f8, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6e907eaf, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5f8a0e8f, org.springframework.security.web.session.SessionManagementFilter@6c31d9c2, org.springframework.security.web.access.ExceptionTranslationFilter@51cff990] +2024-10-01T19:13:47.372+09:00 WARN 44119 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.global.auth.config.SecurityConfig +2024-10-01T19:13:48.810+09:00 INFO 44119 --- [restartedMain] o.s.s.w.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@29b0a200, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@36ee9865, org.springframework.security.web.context.SecurityContextHolderFilter@36dcfa87, org.springframework.security.web.header.HeaderWriterFilter@4577a1fa, org.springframework.web.filter.CorsFilter@3fcf0fd2, org.springframework.security.web.authentication.logout.LogoutFilter@206ab993, com.favoriteplace.global.auth.filter.ExceptionHandlerFilter@a32c846, com.favoriteplace.global.auth.filter.JwtAuthenticationFilter@31e98479, com.favoriteplace.global.auth.filter.LoginFilter@1de580e6, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5b7244f8, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6e907eaf, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5f8a0e8f, org.springframework.security.web.session.SessionManagementFilter@6c31d9c2, org.springframework.security.web.access.ExceptionTranslationFilter@51cff990] 2024-10-01T19:13:49.391+09:00 INFO 44119 --- [restartedMain] o.a.c.h.Http11NioProtocol : Starting ProtocolHandler ["http-nio-8080"] 2024-10-01T19:13:49.408+09:00 INFO 44119 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2024-10-01T19:13:49.411+09:00 INFO 44119 --- [restartedMain] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... @@ -153,7 +153,7 @@ 2024-10-01T19:16:30.700+09:00 INFO 46018 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.favoriteplace.app.repository.VisitedPilgrimageRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository 2024-10-01T19:16:30.701+09:00 INFO 46018 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 60 ms. Found 0 Redis repository interfaces. 2024-10-01T19:16:31.161+09:00 INFO 46018 --- [restartedMain] o.s.c.c.s.GenericScope : BeanFactory id=f56eb2bf-d308-3960-b992-e76803ef57a9 -2024-10-01T19:16:31.262+09:00 INFO 46018 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.security.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2024-10-01T19:16:31.262+09:00 INFO 46018 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.auth.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2024-10-01T19:16:32.002+09:00 INFO 46018 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2024-10-01T19:16:32.029+09:00 INFO 46018 --- [restartedMain] o.a.c.h.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-8080"] 2024-10-01T19:16:32.038+09:00 INFO 46018 --- [restartedMain] o.a.c.c.StandardService : Starting service [Tomcat] @@ -192,8 +192,8 @@ 2024-10-01T19:16:37.945+09:00 WARN 46018 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.BlockRepository 2024-10-01T19:16:37.965+09:00 WARN 46018 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.CompleteRallyRepository 2024-10-01T19:16:38.024+09:00 WARN 46018 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.AddressRepository -2024-10-01T19:16:38.142+09:00 WARN 46018 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.global.security.config.SecurityConfig -2024-10-01T19:16:39.462+09:00 INFO 46018 --- [restartedMain] o.s.s.w.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@244b82ba, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@56ae77e4, org.springframework.security.web.context.SecurityContextHolderFilter@44781b76, org.springframework.security.web.header.HeaderWriterFilter@492eda32, org.springframework.web.filter.CorsFilter@2d1fd3f7, org.springframework.security.web.authentication.logout.LogoutFilter@3cb930b7, com.favoriteplace.global.security.filter.ExceptionHandlerFilter@77bf20d7, com.favoriteplace.global.security.filter.JwtAuthenticationFilter@74158b28, com.favoriteplace.global.security.filter.LoginFilter@c338942, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@6056707a, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6c8e6c4a, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@2907ce77, org.springframework.security.web.session.SessionManagementFilter@53565bfe, org.springframework.security.web.access.ExceptionTranslationFilter@428d0b65] +2024-10-01T19:16:38.142+09:00 WARN 46018 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.global.auth.config.SecurityConfig +2024-10-01T19:16:39.462+09:00 INFO 46018 --- [restartedMain] o.s.s.w.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@244b82ba, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@56ae77e4, org.springframework.security.web.context.SecurityContextHolderFilter@44781b76, org.springframework.security.web.header.HeaderWriterFilter@492eda32, org.springframework.web.filter.CorsFilter@2d1fd3f7, org.springframework.security.web.authentication.logout.LogoutFilter@3cb930b7, com.favoriteplace.global.auth.filter.ExceptionHandlerFilter@77bf20d7, com.favoriteplace.global.auth.filter.JwtAuthenticationFilter@74158b28, com.favoriteplace.global.auth.filter.LoginFilter@c338942, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@6056707a, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6c8e6c4a, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@2907ce77, org.springframework.security.web.session.SessionManagementFilter@53565bfe, org.springframework.security.web.access.ExceptionTranslationFilter@428d0b65] 2024-10-01T19:16:40.128+09:00 INFO 46018 --- [restartedMain] o.a.c.h.Http11NioProtocol : Starting ProtocolHandler ["http-nio-8080"] 2024-10-01T19:16:40.146+09:00 INFO 46018 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2024-10-01T19:16:40.149+09:00 INFO 46018 --- [restartedMain] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... @@ -262,7 +262,7 @@ 2024-10-01T19:19:34.182+09:00 INFO 48178 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.favoriteplace.app.repository.VisitedPilgrimageRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository 2024-10-01T19:19:34.182+09:00 INFO 48178 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 26 ms. Found 0 Redis repository interfaces. 2024-10-01T19:19:34.543+09:00 INFO 48178 --- [restartedMain] o.s.c.c.s.GenericScope : BeanFactory id=f56eb2bf-d308-3960-b992-e76803ef57a9 -2024-10-01T19:19:34.648+09:00 INFO 48178 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.security.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2024-10-01T19:19:34.648+09:00 INFO 48178 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.auth.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2024-10-01T19:19:35.701+09:00 INFO 48178 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2024-10-01T19:19:35.727+09:00 INFO 48178 --- [restartedMain] o.a.c.h.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-8080"] 2024-10-01T19:19:35.730+09:00 INFO 48178 --- [restartedMain] o.a.c.c.StandardService : Starting service [Tomcat] @@ -301,8 +301,8 @@ 2024-10-01T19:19:42.033+09:00 WARN 48178 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.BlockRepository 2024-10-01T19:19:42.059+09:00 WARN 48178 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.CompleteRallyRepository 2024-10-01T19:19:42.100+09:00 WARN 48178 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.AddressRepository -2024-10-01T19:19:42.176+09:00 WARN 48178 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.global.security.config.SecurityConfig -2024-10-01T19:19:44.034+09:00 INFO 48178 --- [restartedMain] o.s.s.w.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@244b82ba, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@56ae77e4, org.springframework.security.web.context.SecurityContextHolderFilter@44781b76, org.springframework.security.web.header.HeaderWriterFilter@492eda32, org.springframework.web.filter.CorsFilter@2d1fd3f7, org.springframework.security.web.authentication.logout.LogoutFilter@3cb930b7, com.favoriteplace.global.security.filter.ExceptionHandlerFilter@20531e41, com.favoriteplace.global.security.filter.JwtAuthenticationFilter@74158b28, com.favoriteplace.global.security.filter.LoginFilter@c338942, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@6056707a, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6c8e6c4a, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@2907ce77, org.springframework.security.web.session.SessionManagementFilter@53565bfe, org.springframework.security.web.access.ExceptionTranslationFilter@428d0b65] +2024-10-01T19:19:42.176+09:00 WARN 48178 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.global.auth.config.SecurityConfig +2024-10-01T19:19:44.034+09:00 INFO 48178 --- [restartedMain] o.s.s.w.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@244b82ba, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@56ae77e4, org.springframework.security.web.context.SecurityContextHolderFilter@44781b76, org.springframework.security.web.header.HeaderWriterFilter@492eda32, org.springframework.web.filter.CorsFilter@2d1fd3f7, org.springframework.security.web.authentication.logout.LogoutFilter@3cb930b7, com.favoriteplace.global.auth.filter.ExceptionHandlerFilter@20531e41, com.favoriteplace.global.auth.filter.JwtAuthenticationFilter@74158b28, com.favoriteplace.global.auth.filter.LoginFilter@c338942, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@6056707a, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6c8e6c4a, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@2907ce77, org.springframework.security.web.session.SessionManagementFilter@53565bfe, org.springframework.security.web.access.ExceptionTranslationFilter@428d0b65] 2024-10-01T19:19:44.667+09:00 INFO 48178 --- [restartedMain] o.a.c.h.Http11NioProtocol : Starting ProtocolHandler ["http-nio-8080"] 2024-10-01T19:19:44.689+09:00 INFO 48178 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2024-10-01T19:19:44.693+09:00 INFO 48178 --- [restartedMain] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... @@ -371,7 +371,7 @@ 2024-10-01T19:21:38.958+09:00 INFO 49585 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.favoriteplace.app.repository.VisitedPilgrimageRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository 2024-10-01T19:21:38.958+09:00 INFO 49585 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 23 ms. Found 0 Redis repository interfaces. 2024-10-01T19:21:39.380+09:00 INFO 49585 --- [restartedMain] o.s.c.c.s.GenericScope : BeanFactory id=f56eb2bf-d308-3960-b992-e76803ef57a9 -2024-10-01T19:21:39.450+09:00 INFO 49585 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.security.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2024-10-01T19:21:39.450+09:00 INFO 49585 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.auth.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2024-10-01T19:21:40.439+09:00 INFO 49585 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2024-10-01T19:21:40.449+09:00 INFO 49585 --- [restartedMain] o.a.c.h.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-8080"] 2024-10-01T19:21:40.451+09:00 INFO 49585 --- [restartedMain] o.a.c.c.StandardService : Starting service [Tomcat] @@ -410,7 +410,7 @@ 2024-10-01T19:21:46.883+09:00 WARN 49585 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.BlockRepository 2024-10-01T19:21:46.903+09:00 WARN 49585 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.CompleteRallyRepository 2024-10-01T19:21:46.959+09:00 WARN 49585 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.AddressRepository -2024-10-01T19:21:47.054+09:00 WARN 49585 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.global.security.config.SecurityConfig +2024-10-01T19:21:47.054+09:00 WARN 49585 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.global.auth.config.SecurityConfig 2024-10-01T19:21:51.572+09:00 INFO 49711 --- [background-preinit] o.h.v.i.u.Version : HV000001: Hibernate Validator 8.0.1.Final 2024-10-01T19:21:51.648+09:00 INFO 49711 --- [restartedMain] c.f.FavoritePlaceApplication : Starting FavoritePlaceApplication using Java 21.0.1 with PID 49711 (/Users/sinjeong-yun/Documents/최애의 장소/Server/out/production/classes started by sinjeong-yun in /Users/sinjeong-yun/Documents/최애의 장소/Server) 2024-10-01T19:21:51.653+09:00 INFO 49711 --- [restartedMain] c.f.FavoritePlaceApplication : No active profile set, falling back to 1 default profile: "default" @@ -462,7 +462,7 @@ 2024-10-01T19:21:54.096+09:00 INFO 49711 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.favoriteplace.app.repository.VisitedPilgrimageRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository 2024-10-01T19:21:54.096+09:00 INFO 49711 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 39 ms. Found 0 Redis repository interfaces. 2024-10-01T19:21:54.608+09:00 INFO 49711 --- [restartedMain] o.s.c.c.s.GenericScope : BeanFactory id=f56eb2bf-d308-3960-b992-e76803ef57a9 -2024-10-01T19:21:54.702+09:00 INFO 49711 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.security.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2024-10-01T19:21:54.702+09:00 INFO 49711 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.auth.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2024-10-01T19:21:55.621+09:00 INFO 49711 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2024-10-01T19:21:55.641+09:00 INFO 49711 --- [restartedMain] o.a.c.h.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-8080"] 2024-10-01T19:21:55.646+09:00 INFO 49711 --- [restartedMain] o.a.c.c.StandardService : Starting service [Tomcat] @@ -501,8 +501,8 @@ 2024-10-01T19:22:01.933+09:00 WARN 49711 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.BlockRepository 2024-10-01T19:22:01.965+09:00 WARN 49711 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.CompleteRallyRepository 2024-10-01T19:22:02.013+09:00 WARN 49711 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.AddressRepository -2024-10-01T19:22:02.109+09:00 WARN 49711 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.global.security.config.SecurityConfig -2024-10-01T19:22:03.689+09:00 INFO 49711 --- [restartedMain] o.s.s.w.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@6d858264, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@678993ee, org.springframework.security.web.context.SecurityContextHolderFilter@3006ba21, org.springframework.security.web.header.HeaderWriterFilter@8936b2b, org.springframework.web.filter.CorsFilter@4fa43996, org.springframework.security.web.authentication.logout.LogoutFilter@3a3770e, com.favoriteplace.global.security.filter.ExceptionHandlerFilter@2b8c936d, com.favoriteplace.global.security.filter.JwtAuthenticationFilter@78f514ef, com.favoriteplace.global.security.filter.LoginFilter@39223f37, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@2b7931fd, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@8ded021, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@121fdd1e, org.springframework.security.web.session.SessionManagementFilter@33962a84, org.springframework.security.web.access.ExceptionTranslationFilter@6045af66] +2024-10-01T19:22:02.109+09:00 WARN 49711 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.global.auth.config.SecurityConfig +2024-10-01T19:22:03.689+09:00 INFO 49711 --- [restartedMain] o.s.s.w.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@6d858264, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@678993ee, org.springframework.security.web.context.SecurityContextHolderFilter@3006ba21, org.springframework.security.web.header.HeaderWriterFilter@8936b2b, org.springframework.web.filter.CorsFilter@4fa43996, org.springframework.security.web.authentication.logout.LogoutFilter@3a3770e, com.favoriteplace.global.auth.filter.ExceptionHandlerFilter@2b8c936d, com.favoriteplace.global.auth.filter.JwtAuthenticationFilter@78f514ef, com.favoriteplace.global.auth.filter.LoginFilter@39223f37, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@2b7931fd, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@8ded021, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@121fdd1e, org.springframework.security.web.session.SessionManagementFilter@33962a84, org.springframework.security.web.access.ExceptionTranslationFilter@6045af66] 2024-10-01T19:22:04.514+09:00 INFO 49711 --- [restartedMain] o.a.c.h.Http11NioProtocol : Starting ProtocolHandler ["http-nio-8080"] 2024-10-01T19:22:04.548+09:00 INFO 49711 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2024-10-01T19:22:04.552+09:00 INFO 49711 --- [restartedMain] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... @@ -566,7 +566,7 @@ 2024-10-01T19:35:36.152+09:00 INFO 59095 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.favoriteplace.app.repository.VisitedPilgrimageRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository 2024-10-01T19:35:36.152+09:00 INFO 59095 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 36 ms. Found 0 Redis repository interfaces. 2024-10-01T19:35:36.549+09:00 INFO 59095 --- [restartedMain] o.s.c.c.s.GenericScope : BeanFactory id=f56eb2bf-d308-3960-b992-e76803ef57a9 -2024-10-01T19:35:36.613+09:00 INFO 59095 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.security.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2024-10-01T19:35:36.613+09:00 INFO 59095 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.auth.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2024-10-01T19:35:37.397+09:00 INFO 59095 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2024-10-01T19:35:37.417+09:00 INFO 59095 --- [restartedMain] o.a.c.h.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-8080"] 2024-10-01T19:35:37.420+09:00 INFO 59095 --- [restartedMain] o.a.c.c.StandardService : Starting service [Tomcat] @@ -605,8 +605,8 @@ 2024-10-01T19:35:42.970+09:00 WARN 59095 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.BlockRepository 2024-10-01T19:35:42.986+09:00 WARN 59095 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.CompleteRallyRepository 2024-10-01T19:35:43.022+09:00 WARN 59095 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.AddressRepository -2024-10-01T19:35:43.097+09:00 WARN 59095 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.global.security.config.SecurityConfig -2024-10-01T19:35:44.622+09:00 INFO 59095 --- [restartedMain] o.s.s.w.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@3ad3ed2c, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@49d6ff8a, org.springframework.security.web.context.SecurityContextHolderFilter@cd02ada, org.springframework.security.web.header.HeaderWriterFilter@2ea5d5ff, org.springframework.web.filter.CorsFilter@3d2ff82e, org.springframework.security.web.authentication.logout.LogoutFilter@45796513, com.favoriteplace.global.security.filter.ExceptionHandlerFilter@8fa555a, com.favoriteplace.global.security.filter.JwtAuthenticationFilter@52d4dd44, com.favoriteplace.global.security.filter.LoginFilter@77cbf0bf, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@6592374a, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@656808c9, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@99f7b63, org.springframework.security.web.session.SessionManagementFilter@62ff75f7, org.springframework.security.web.access.ExceptionTranslationFilter@51c8759b] +2024-10-01T19:35:43.097+09:00 WARN 59095 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.global.auth.config.SecurityConfig +2024-10-01T19:35:44.622+09:00 INFO 59095 --- [restartedMain] o.s.s.w.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@3ad3ed2c, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@49d6ff8a, org.springframework.security.web.context.SecurityContextHolderFilter@cd02ada, org.springframework.security.web.header.HeaderWriterFilter@2ea5d5ff, org.springframework.web.filter.CorsFilter@3d2ff82e, org.springframework.security.web.authentication.logout.LogoutFilter@45796513, com.favoriteplace.global.auth.filter.ExceptionHandlerFilter@8fa555a, com.favoriteplace.global.auth.filter.JwtAuthenticationFilter@52d4dd44, com.favoriteplace.global.auth.filter.LoginFilter@77cbf0bf, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@6592374a, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@656808c9, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@99f7b63, org.springframework.security.web.session.SessionManagementFilter@62ff75f7, org.springframework.security.web.access.ExceptionTranslationFilter@51c8759b] 2024-10-01T19:35:45.664+09:00 INFO 59095 --- [restartedMain] o.a.c.h.Http11NioProtocol : Starting ProtocolHandler ["http-nio-8080"] 2024-10-01T19:35:45.697+09:00 INFO 59095 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2024-10-01T19:35:45.700+09:00 INFO 59095 --- [restartedMain] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... @@ -675,7 +675,7 @@ 2024-10-01T19:37:50.202+09:00 INFO 60656 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.favoriteplace.app.repository.VisitedPilgrimageRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository 2024-10-01T19:37:50.202+09:00 INFO 60656 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 32 ms. Found 0 Redis repository interfaces. 2024-10-01T19:37:50.522+09:00 INFO 60656 --- [restartedMain] o.s.c.c.s.GenericScope : BeanFactory id=f56eb2bf-d308-3960-b992-e76803ef57a9 -2024-10-01T19:37:50.585+09:00 INFO 60656 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.security.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2024-10-01T19:37:50.585+09:00 INFO 60656 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.auth.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2024-10-01T19:37:51.266+09:00 INFO 60656 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2024-10-01T19:37:51.275+09:00 INFO 60656 --- [restartedMain] o.a.c.h.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-8080"] 2024-10-01T19:37:51.278+09:00 INFO 60656 --- [restartedMain] o.a.c.c.StandardService : Starting service [Tomcat] @@ -714,8 +714,8 @@ 2024-10-01T19:37:57.966+09:00 WARN 60656 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.BlockRepository 2024-10-01T19:37:57.982+09:00 WARN 60656 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.CompleteRallyRepository 2024-10-01T19:37:58.024+09:00 WARN 60656 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.app.repository.AddressRepository -2024-10-01T19:37:58.122+09:00 WARN 60656 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.global.security.config.SecurityConfig -2024-10-01T19:37:59.681+09:00 INFO 60656 --- [restartedMain] o.s.s.w.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@6c1e6d4b, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@5b9f94f0, org.springframework.security.web.context.SecurityContextHolderFilter@17340c55, org.springframework.security.web.header.HeaderWriterFilter@5c220909, org.springframework.web.filter.CorsFilter@10c80423, org.springframework.security.web.authentication.logout.LogoutFilter@3b309aea, com.favoriteplace.global.security.filter.ExceptionHandlerFilter@3b56fa11, com.favoriteplace.global.security.filter.JwtAuthenticationFilter@7e1f4edb, com.favoriteplace.global.security.filter.LoginFilter@61740066, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@4169a44f, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6fde83db, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@46eb20ac, org.springframework.security.web.session.SessionManagementFilter@78175c90, org.springframework.security.web.access.ExceptionTranslationFilter@3fb89bdd] +2024-10-01T19:37:58.122+09:00 WARN 60656 --- [restartedMain] o.s.c.LocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.favoriteplace.global.auth.config.SecurityConfig +2024-10-01T19:37:59.681+09:00 INFO 60656 --- [restartedMain] o.s.s.w.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@6c1e6d4b, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@5b9f94f0, org.springframework.security.web.context.SecurityContextHolderFilter@17340c55, org.springframework.security.web.header.HeaderWriterFilter@5c220909, org.springframework.web.filter.CorsFilter@10c80423, org.springframework.security.web.authentication.logout.LogoutFilter@3b309aea, com.favoriteplace.global.auth.filter.ExceptionHandlerFilter@3b56fa11, com.favoriteplace.global.auth.filter.JwtAuthenticationFilter@7e1f4edb, com.favoriteplace.global.auth.filter.LoginFilter@61740066, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@4169a44f, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6fde83db, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@46eb20ac, org.springframework.security.web.session.SessionManagementFilter@78175c90, org.springframework.security.web.access.ExceptionTranslationFilter@3fb89bdd] 2024-10-01T19:38:00.657+09:00 INFO 60656 --- [restartedMain] o.a.c.h.Http11NioProtocol : Starting ProtocolHandler ["http-nio-8080"] 2024-10-01T19:38:00.681+09:00 INFO 60656 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2024-10-01T19:38:00.690+09:00 INFO 60656 --- [restartedMain] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... @@ -787,7 +787,7 @@ 2024-10-01T19:47:35.623+09:00 INFO 60656 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.favoriteplace.app.repository.VisitedPilgrimageRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository 2024-10-01T19:47:35.623+09:00 INFO 60656 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 32 ms. Found 0 Redis repository interfaces. 2024-10-01T19:47:35.815+09:00 INFO 60656 --- [restartedMain] o.s.c.c.s.GenericScope : BeanFactory id=f56eb2bf-d308-3960-b992-e76803ef57a9 -2024-10-01T19:47:35.842+09:00 INFO 60656 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.security.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2024-10-01T19:47:35.842+09:00 INFO 60656 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.auth.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2024-10-01T19:47:36.044+09:00 INFO 60656 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2024-10-01T19:47:36.046+09:00 INFO 60656 --- [restartedMain] o.a.c.h.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-8080"] 2024-10-01T19:47:36.046+09:00 INFO 60656 --- [restartedMain] o.a.c.c.StandardService : Starting service [Tomcat] @@ -1081,7 +1081,7 @@ Caused by: java.lang.IllegalStateException: FirebaseApp name [DEFAULT] already e 2024-10-01T19:47:40.820+09:00 INFO 60656 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.favoriteplace.app.repository.VisitedPilgrimageRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository 2024-10-01T19:47:40.820+09:00 INFO 60656 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 19 ms. Found 0 Redis repository interfaces. 2024-10-01T19:47:40.974+09:00 INFO 60656 --- [restartedMain] o.s.c.c.s.GenericScope : BeanFactory id=f56eb2bf-d308-3960-b992-e76803ef57a9 -2024-10-01T19:47:40.997+09:00 INFO 60656 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.security.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2024-10-01T19:47:40.997+09:00 INFO 60656 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.auth.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2024-10-01T19:47:41.077+09:00 INFO 60656 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2024-10-01T19:47:41.078+09:00 INFO 60656 --- [restartedMain] o.a.c.h.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-8080"] 2024-10-01T19:47:41.078+09:00 INFO 60656 --- [restartedMain] o.a.c.c.StandardService : Starting service [Tomcat] @@ -1375,7 +1375,7 @@ Caused by: java.lang.IllegalStateException: FirebaseApp name [DEFAULT] already e 2024-10-01T19:47:46.142+09:00 INFO 60656 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.favoriteplace.app.repository.VisitedPilgrimageRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository 2024-10-01T19:47:46.142+09:00 INFO 60656 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 21 ms. Found 0 Redis repository interfaces. 2024-10-01T19:47:46.220+09:00 INFO 60656 --- [restartedMain] o.s.c.c.s.GenericScope : BeanFactory id=f56eb2bf-d308-3960-b992-e76803ef57a9 -2024-10-01T19:47:46.229+09:00 INFO 60656 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.security.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2024-10-01T19:47:46.229+09:00 INFO 60656 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.auth.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2024-10-01T19:47:46.289+09:00 INFO 60656 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2024-10-01T19:47:46.290+09:00 INFO 60656 --- [restartedMain] o.a.c.h.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-8080"] 2024-10-01T19:47:46.290+09:00 INFO 60656 --- [restartedMain] o.a.c.c.StandardService : Starting service [Tomcat] @@ -1669,7 +1669,7 @@ Caused by: java.lang.IllegalStateException: FirebaseApp name [DEFAULT] already e 2024-10-01T19:48:21.204+09:00 INFO 60656 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.favoriteplace.app.repository.VisitedPilgrimageRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository 2024-10-01T19:48:21.204+09:00 INFO 60656 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 29 ms. Found 0 Redis repository interfaces. 2024-10-01T19:48:21.301+09:00 INFO 60656 --- [restartedMain] o.s.c.c.s.GenericScope : BeanFactory id=f56eb2bf-d308-3960-b992-e76803ef57a9 -2024-10-01T19:48:21.310+09:00 INFO 60656 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.security.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2024-10-01T19:48:21.310+09:00 INFO 60656 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.auth.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2024-10-01T19:48:21.365+09:00 INFO 60656 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2024-10-01T19:48:21.366+09:00 INFO 60656 --- [restartedMain] o.a.c.h.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-8080"] 2024-10-01T19:48:21.366+09:00 INFO 60656 --- [restartedMain] o.a.c.c.StandardService : Starting service [Tomcat] @@ -1963,7 +1963,7 @@ Caused by: java.lang.IllegalStateException: FirebaseApp name [DEFAULT] already e 2024-10-01T19:48:24.424+09:00 INFO 60656 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.favoriteplace.app.repository.VisitedPilgrimageRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository 2024-10-01T19:48:24.424+09:00 INFO 60656 --- [restartedMain] o.s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 12 ms. Found 0 Redis repository interfaces. 2024-10-01T19:48:24.484+09:00 INFO 60656 --- [restartedMain] o.s.c.c.s.GenericScope : BeanFactory id=f56eb2bf-d308-3960-b992-e76803ef57a9 -2024-10-01T19:48:24.494+09:00 INFO 60656 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.security.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2024-10-01T19:48:24.494+09:00 INFO 60656 --- [restartedMain] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker : Bean 'com.favoriteplace.global.auth.kakao.KakaoClient' of type [org.springframework.cloud.openfeign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2024-10-01T19:48:24.544+09:00 INFO 60656 --- [restartedMain] o.s.b.w.e.t.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2024-10-01T19:48:24.546+09:00 INFO 60656 --- [restartedMain] o.a.c.h.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-8080"] 2024-10-01T19:48:24.546+09:00 INFO 60656 --- [restartedMain] o.a.c.c.StandardService : Starting service [Tomcat] diff --git a/src/main/java/com/favoriteplace/app/controller/MemberController.java b/src/main/java/com/favoriteplace/app/controller/MemberController.java index affe426a..701b719d 100644 --- a/src/main/java/com/favoriteplace/app/controller/MemberController.java +++ b/src/main/java/com/favoriteplace/app/controller/MemberController.java @@ -6,10 +6,10 @@ import com.favoriteplace.app.dto.member.MemberDto.EmailDuplicateResDto; import com.favoriteplace.app.dto.member.MemberDto.EmailSendResDto; import com.favoriteplace.app.dto.member.MemberDto.MemberSignUpReqDto; -import com.favoriteplace.app.dto.member.MemberDto.TokenInfo; +import com.favoriteplace.app.dto.member.TokenInfoDto; import com.favoriteplace.app.service.MailSendService; import com.favoriteplace.app.service.MemberService; -import com.favoriteplace.global.security.provider.JwtTokenProvider; +import com.favoriteplace.global.auth.provider.JwtTokenProvider; import com.favoriteplace.global.util.SecurityUtil; import jakarta.servlet.http.HttpServletRequest; @@ -40,7 +40,7 @@ public class MemberController { private final SecurityUtil securityUtil; @PostMapping("/login/kakao") - public ResponseEntity kakaoLogin( + public ResponseEntity kakaoLogin( @RequestHeader("Authorization") final String token ) { return ResponseEntity.ok(memberService.kakaoLogin(token)); diff --git a/src/main/java/com/favoriteplace/app/controller/PilgrimageSocketController.java b/src/main/java/com/favoriteplace/app/controller/PilgrimageSocketController.java index ffc5669d..021d3805 100644 --- a/src/main/java/com/favoriteplace/app/controller/PilgrimageSocketController.java +++ b/src/main/java/com/favoriteplace/app/controller/PilgrimageSocketController.java @@ -3,12 +3,11 @@ import com.favoriteplace.app.domain.Member; import com.favoriteplace.app.dto.CommonResponseDto; import com.favoriteplace.app.dto.travel.PilgrimageCertifyRequestDto; -import com.favoriteplace.app.dto.travel.PilgrimageResponseDto; import com.favoriteplace.app.dto.travel.PilgrimageSocketDto; import com.favoriteplace.app.service.PilgrimageCommandService; import com.favoriteplace.global.exception.ErrorCode; import com.favoriteplace.global.exception.RestApiException; -import com.favoriteplace.global.security.CustomUserDetails; +import com.favoriteplace.global.auth.CustomUserDetails; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/com/favoriteplace/app/dto/member/MemberDto.java b/src/main/java/com/favoriteplace/app/dto/member/MemberDto.java index 8c4e9ffe..6ae325ba 100644 --- a/src/main/java/com/favoriteplace/app/dto/member/MemberDto.java +++ b/src/main/java/com/favoriteplace/app/dto/member/MemberDto.java @@ -51,14 +51,14 @@ public static class MemberSignUpResDto { private String accessToken; private String refreshToken; - public static MemberSignUpResDto from(Member member, TokenInfo tokenInfo) { + public static MemberSignUpResDto from(Member member, TokenInfoDto tokenInfo) { return MemberSignUpResDto.builder() .nickname(member.getNickname()) .introduction(member.getDescription()) .profileImage(member.getProfileImageUrl()) .profileTitleItem(member.getProfileTitle().getDefaultImage().getUrl()) - .accessToken(tokenInfo.accessToken) - .refreshToken(tokenInfo.refreshToken) + .accessToken(tokenInfo.accessToken()) + .refreshToken(tokenInfo.refreshToken()) .build(); } } @@ -108,16 +108,6 @@ public static class EmailCheckReqDto { private Integer authNum; } - @Builder - @Getter - @AllArgsConstructor - public static class TokenInfo { - - private String grantType; - private String accessToken; - private String refreshToken; - } - @Builder @Getter @AllArgsConstructor diff --git a/src/main/java/com/favoriteplace/app/dto/member/TokenInfoDto.java b/src/main/java/com/favoriteplace/app/dto/member/TokenInfoDto.java new file mode 100644 index 00000000..8d21dae6 --- /dev/null +++ b/src/main/java/com/favoriteplace/app/dto/member/TokenInfoDto.java @@ -0,0 +1,14 @@ +package com.favoriteplace.app.dto.member; + +public record TokenInfoDto( + String grantType, + String accessToken, + String refreshToken +) { + public static TokenInfoDto of( + final String accessToken, + final String refreshToken + ) { + return new TokenInfoDto("Bearer", accessToken, refreshToken); + } +} diff --git a/src/main/java/com/favoriteplace/app/service/MemberService.java b/src/main/java/com/favoriteplace/app/service/MemberService.java index 64e10674..d8667de5 100644 --- a/src/main/java/com/favoriteplace/app/service/MemberService.java +++ b/src/main/java/com/favoriteplace/app/service/MemberService.java @@ -14,12 +14,13 @@ import com.favoriteplace.app.dto.member.MemberDto.EmailDuplicateResDto; import com.favoriteplace.app.dto.member.MemberDto.EmailSendReqDto; import com.favoriteplace.app.dto.member.MemberDto.MemberSignUpReqDto; +import com.favoriteplace.app.dto.member.TokenInfoDto; import com.favoriteplace.app.repository.ItemRepository; import com.favoriteplace.app.repository.MemberRepository; import com.favoriteplace.global.exception.RestApiException; import com.favoriteplace.global.s3Image.AmazonS3ImageManager; -import com.favoriteplace.global.security.kakao.KakaoClient; -import com.favoriteplace.global.security.provider.JwtTokenProvider; +import com.favoriteplace.global.auth.kakao.KakaoClient; +import com.favoriteplace.global.auth.provider.JwtTokenProvider; import com.favoriteplace.global.util.SecurityUtil; import java.io.IOException; @@ -49,7 +50,7 @@ public class MemberService { private final RedisTemplate redisTemplate; private final KakaoClient kakaoClient; - public MemberDto.TokenInfo kakaoLogin(final String token) { + public TokenInfoDto kakaoLogin(final String token) { AuthKakaoLoginDto userInfo = kakaoClient.getUserInfo(token); // 최초 로그인이라면 회원가입 API로 통신하도록 @@ -83,8 +84,8 @@ public MemberDto.MemberSignUpResDto kakaoSignUp( Member member = memberSignUpReqDto.toEntity(profileImageUrl, titleItem, userEmail); memberRepository.save(member); - MemberDto.TokenInfo tokenInfo = jwtTokenProvider.generateToken(userEmail); - member.updateRefreshToken(tokenInfo.getRefreshToken()); + TokenInfoDto tokenInfo = jwtTokenProvider.generateToken(userEmail); + member.updateRefreshToken(tokenInfo.refreshToken()); return MemberDto.MemberSignUpResDto.from(member, tokenInfo); @@ -115,8 +116,8 @@ public MemberDto.MemberSignUpResDto signup( Member member = memberSignUpReqDto.toEntity(password, profileImageUrl, titleItem); memberRepository.save(member); - MemberDto.TokenInfo tokenInfo = jwtTokenProvider.generateToken(member.getEmail()); - member.updateRefreshToken(tokenInfo.getRefreshToken()); + TokenInfoDto tokenInfo = jwtTokenProvider.generateToken(member.getEmail()); + member.updateRefreshToken(tokenInfo.refreshToken()); return MemberDto.MemberSignUpResDto.from(member, tokenInfo); } From 8ac9779a711fddd20fb80969e09e8360b043ffdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9C=A4?= Date: Thu, 16 Jan 2025 01:20:02 +0900 Subject: [PATCH 3/9] =?UTF-8?q?[refactor]=20=EC=9D=B8=EC=A6=9D=EC=9D=B4=20?= =?UTF-8?q?=ED=95=84=EC=88=98=EC=9D=B8=20EndPoint=20=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존 JwtAuthenticationFilter에서 관리하던 인증 필수 EndPoint를 클래스로 분리했습니다. --- .../auth/JwtAuthenticationNeededPath.java | 54 ++++++++++++ .../auth/filter/JwtAuthenticationFilter.java | 83 +++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 src/main/java/com/favoriteplace/global/auth/JwtAuthenticationNeededPath.java create mode 100644 src/main/java/com/favoriteplace/global/auth/filter/JwtAuthenticationFilter.java diff --git a/src/main/java/com/favoriteplace/global/auth/JwtAuthenticationNeededPath.java b/src/main/java/com/favoriteplace/global/auth/JwtAuthenticationNeededPath.java new file mode 100644 index 00000000..fcba7bb1 --- /dev/null +++ b/src/main/java/com/favoriteplace/global/auth/JwtAuthenticationNeededPath.java @@ -0,0 +1,54 @@ +package com.favoriteplace.global.auth; + +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; + +@RequiredArgsConstructor +public class JwtAuthenticationNeededPath { + private final String pathPattern; + private final String method; + + public boolean matches(String requestURI, String method) { + String regex = pathPattern.replaceAll("\\*\\*", ".*"); + return Pattern.matches(regex, requestURI) && this.method.equalsIgnoreCase(method); + } + + public static final List NEEDED_JWT_AUTHENTICATION_PATHS = Arrays.asList( + new JwtAuthenticationNeededPath("/auth/logout", "POST"), + new JwtAuthenticationNeededPath("/pilgrimage/**", "POST"), + new JwtAuthenticationNeededPath("/pilgrimage/**", "DELETE"), + new JwtAuthenticationNeededPath("/posts/free/my-posts", "GET"), + new JwtAuthenticationNeededPath("/posts/free/my-comments", "GET"), + new JwtAuthenticationNeededPath("/posts/free", "POST"), + new JwtAuthenticationNeededPath("/posts/free/**", "DELETE"), + new JwtAuthenticationNeededPath("/posts/free/**", "POST"), + new JwtAuthenticationNeededPath("/posts/free/**", "PUT"), + new JwtAuthenticationNeededPath("/posts/free/**", "PATCH"), + new JwtAuthenticationNeededPath("/posts/guestbooks/my-comments", "GET"), + new JwtAuthenticationNeededPath("/posts/guestbooks/my-posts", "GET"), + new JwtAuthenticationNeededPath("/my", "GET"), + new JwtAuthenticationNeededPath("/my/**", "GET"), + new JwtAuthenticationNeededPath("/my/**", "PUT"), + new JwtAuthenticationNeededPath("/my/**", "PATCH"), + new JwtAuthenticationNeededPath("/posts/guestbooks/**", "PATCH"), + new JwtAuthenticationNeededPath("/posts/guestbooks/**", "DELETE"), + new JwtAuthenticationNeededPath("/posts/guestbooks/**", "POST"), + new JwtAuthenticationNeededPath("/my/blocks/**", "POST"), + new JwtAuthenticationNeededPath("/posts/free/comments/**", "PUT"), + new JwtAuthenticationNeededPath("/posts/free/comments/**", "DELETE"), + new JwtAuthenticationNeededPath("/posts/guestbooks/comments/**", "PUT"), + new JwtAuthenticationNeededPath("/posts/guestbooks/comments/**", "DELETE"), + new JwtAuthenticationNeededPath("/shop/purchase/**", "POST"), + new JwtAuthenticationNeededPath("/notifications", "PATCH"), + new JwtAuthenticationNeededPath("/notifications", "GET"), + new JwtAuthenticationNeededPath("/notifications/**", "PATCH"), + new JwtAuthenticationNeededPath("/notifications/**", "DELETE") + ); + + public static List getNeededPaths() { + return NEEDED_JWT_AUTHENTICATION_PATHS; + } +} diff --git a/src/main/java/com/favoriteplace/global/auth/filter/JwtAuthenticationFilter.java b/src/main/java/com/favoriteplace/global/auth/filter/JwtAuthenticationFilter.java new file mode 100644 index 00000000..a64b0af0 --- /dev/null +++ b/src/main/java/com/favoriteplace/global/auth/filter/JwtAuthenticationFilter.java @@ -0,0 +1,83 @@ +package com.favoriteplace.global.auth.filter; + +import com.favoriteplace.global.auth.JwtAuthenticationNeededPath; +import com.favoriteplace.global.exception.ErrorCode; +import com.favoriteplace.global.exception.RestApiException; +import com.favoriteplace.global.auth.provider.JwtTokenProvider; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import static com.favoriteplace.global.exception.ErrorCode.INVALID_BEARER_PREFIX; +import static com.favoriteplace.global.exception.ErrorCode.MISSING_AUTHORIZATION_JWT; + +@RequiredArgsConstructor +@Slf4j +public class JwtAuthenticationFilter extends OncePerRequestFilter { + + private final JwtTokenProvider jwtTokenProvider; + private final RedisTemplate redisTemplate; + + @Override + protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { + String requestURI = request.getServletPath(); + String method = request.getMethod(); + + return !JwtAuthenticationNeededPath.NEEDED_JWT_AUTHENTICATION_PATHS.stream() + .anyMatch(excludePath -> excludePath.matches(requestURI, method)); + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + String token = getJwtFromHeader(request); + + if ("websocket".equalsIgnoreCase(request.getHeader("Upgrade"))) { + chain.doFilter(request, response); + return; + } + + jwtTokenProvider.validateToken(token); + + /*1. Redis에 해당 accessToken logout 여부 확인 */ + String isLogout = (String) redisTemplate.opsForValue().get(token); + + if ("logout".equals(isLogout)) { + throw new RestApiException(ErrorCode.TOKEN_NOT_VALID); + } else { + /* 2. 토큰이 유효할 경우 토큰에서 Authentication 객체를 가지고 와서 SecurityContext에 저장 */ + Authentication authentication = jwtTokenProvider.getAuthentication(token); + SecurityContextHolder.getContext().setAuthentication(authentication); + log.info("Security Context에 '{}' 인증 정보를 저장했습니다, uri: {}", authentication.getName(), request.getRequestURI()); + } + + chain.doFilter(request, response); + } + + private String getJwtFromHeader(HttpServletRequest request) { + String bearerToken = request.getHeader("Authorization"); + + if (!StringUtils.hasText(bearerToken)) { + throw new RestApiException(MISSING_AUTHORIZATION_JWT); + } else if (!bearerToken.startsWith("Bearer")) { + throw new RestApiException(INVALID_BEARER_PREFIX); + } + return bearerToken.substring(7); + } + +} \ No newline at end of file From c0f1b13a30deecfff35edb7291994331254aaa72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9C=A4?= Date: Thu, 16 Jan 2025 01:20:40 +0900 Subject: [PATCH 4/9] =?UTF-8?q?[refactor]=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83=20service=EB=8B=A8=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/service/MemberService.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/favoriteplace/app/service/MemberService.java b/src/main/java/com/favoriteplace/app/service/MemberService.java index d8667de5..8650ad49 100644 --- a/src/main/java/com/favoriteplace/app/service/MemberService.java +++ b/src/main/java/com/favoriteplace/app/service/MemberService.java @@ -29,6 +29,7 @@ import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.core.Authentication; import org.springframework.security.crypto.password.PasswordEncoder; @@ -39,6 +40,7 @@ @Service @Transactional(readOnly = true) @RequiredArgsConstructor +@Slf4j public class MemberService { private final MemberRepository memberRepository; @@ -151,13 +153,8 @@ public UserInfoResponseDto getUserInfo(Member member) { } @Transactional - public void logout(String accessToken) { - /*1. Access Token 검증 */ - if (!jwtTokenProvider.validateToken(accessToken)) { - new RestApiException(TOKEN_NOT_VALID); - } - - Authentication authentication = jwtTokenProvider.getAuthentication(accessToken); + public void logout(String token){ + Authentication authentication = jwtTokenProvider.getAuthentication(token); Member member = findMember(authentication.getName()); if (member.getRefreshToken() != null && !member.getRefreshToken().isEmpty()) { @@ -165,9 +162,11 @@ public void logout(String accessToken) { } /* 해당 asscess token 유효시간을 계산해서 blacklist로 저장 */ - Long expriation = jwtTokenProvider.getExpiration(accessToken); + Long expriation = jwtTokenProvider.getExpiration(token); + log.info(String.valueOf(expriation)); redisTemplate.opsForValue() - .set(accessToken, "logout", expriation, TimeUnit.MICROSECONDS); + .set(token, "logout", expriation, TimeUnit.MILLISECONDS); + } public Member findMember(final String email) { From b458a51f3c9f4afceea2bebe7cefaf5b04dfc0d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9C=A4?= Date: Thu, 16 Jan 2025 01:22:52 +0900 Subject: [PATCH 5/9] =?UTF-8?q?[refactor]=20=EC=9D=B8=EC=A6=9D=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=ED=8C=A8=ED=82=A4=EC=A7=80=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존 security에서 auth로 패키지명 변경 --- .../{security => auth}/CustomUserDetails.java | 2 +- .../config/EmailConfig.java | 4 +- .../config/FeignClientConfig.java | 2 +- .../config/JacksonConfig.java | 2 +- .../config/RedisConfig.java | 3 +- .../config/SecurityConfig.java | 23 ++- .../filter/ExceptionHandlerFilter.java | 43 ++--- .../filter/JwtAuthenticationEntryPoint.java | 2 +- .../filter/LoginFilter.java | 9 +- .../CustomAuthenticationFailHandler.java | 18 +- .../CustomAuthenticationSuccessHandler.java | 26 ++- .../handler/JwtAccessDeniedHandler.java | 2 +- .../{security => auth}/kakao/KakaoClient.java | 4 +- .../auth/provider/JwtTokenProvider.java | 98 +++++++++++ .../service/CustomUserDetailsService.java | 9 +- .../global/exception/ErrorCode.java | 13 +- .../filter/JwtAuthenticationFilter.java | 155 ------------------ .../security/provider/JwtTokenProvider.java | 114 ------------- .../global/util/SecurityUtil.java | 4 +- .../websocket/JwtChannelInterceptor.java | 8 +- 20 files changed, 186 insertions(+), 355 deletions(-) rename src/main/java/com/favoriteplace/global/{security => auth}/CustomUserDetails.java (95%) rename src/main/java/com/favoriteplace/global/{security => auth}/config/EmailConfig.java (96%) rename src/main/java/com/favoriteplace/global/{security => auth}/config/FeignClientConfig.java (95%) rename src/main/java/com/favoriteplace/global/{security => auth}/config/JacksonConfig.java (90%) rename src/main/java/com/favoriteplace/global/{security => auth}/config/RedisConfig.java (92%) rename src/main/java/com/favoriteplace/global/{security => auth}/config/SecurityConfig.java (76%) rename src/main/java/com/favoriteplace/global/{security => auth}/filter/ExceptionHandlerFilter.java (58%) rename src/main/java/com/favoriteplace/global/{security => auth}/filter/JwtAuthenticationEntryPoint.java (94%) rename src/main/java/com/favoriteplace/global/{security => auth}/filter/LoginFilter.java (85%) rename src/main/java/com/favoriteplace/global/{security => auth}/handler/CustomAuthenticationFailHandler.java (62%) rename src/main/java/com/favoriteplace/global/{security => auth}/handler/CustomAuthenticationSuccessHandler.java (72%) rename src/main/java/com/favoriteplace/global/{security => auth}/handler/JwtAccessDeniedHandler.java (93%) rename src/main/java/com/favoriteplace/global/{security => auth}/kakao/KakaoClient.java (81%) create mode 100644 src/main/java/com/favoriteplace/global/auth/provider/JwtTokenProvider.java rename src/main/java/com/favoriteplace/global/{security => auth}/service/CustomUserDetailsService.java (79%) delete mode 100644 src/main/java/com/favoriteplace/global/security/filter/JwtAuthenticationFilter.java delete mode 100644 src/main/java/com/favoriteplace/global/security/provider/JwtTokenProvider.java diff --git a/src/main/java/com/favoriteplace/global/security/CustomUserDetails.java b/src/main/java/com/favoriteplace/global/auth/CustomUserDetails.java similarity index 95% rename from src/main/java/com/favoriteplace/global/security/CustomUserDetails.java rename to src/main/java/com/favoriteplace/global/auth/CustomUserDetails.java index c4b70910..064a3143 100644 --- a/src/main/java/com/favoriteplace/global/security/CustomUserDetails.java +++ b/src/main/java/com/favoriteplace/global/auth/CustomUserDetails.java @@ -1,4 +1,4 @@ -package com.favoriteplace.global.security; +package com.favoriteplace.global.auth; import com.favoriteplace.app.domain.Member; import java.util.Collection; diff --git a/src/main/java/com/favoriteplace/global/security/config/EmailConfig.java b/src/main/java/com/favoriteplace/global/auth/config/EmailConfig.java similarity index 96% rename from src/main/java/com/favoriteplace/global/security/config/EmailConfig.java rename to src/main/java/com/favoriteplace/global/auth/config/EmailConfig.java index 9f170326..1c393d3d 100644 --- a/src/main/java/com/favoriteplace/global/security/config/EmailConfig.java +++ b/src/main/java/com/favoriteplace/global/auth/config/EmailConfig.java @@ -1,7 +1,7 @@ -package com.favoriteplace.global.security.config; +package com.favoriteplace.global.auth.config; import java.util.Properties; -import lombok.RequiredArgsConstructor; + import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/com/favoriteplace/global/security/config/FeignClientConfig.java b/src/main/java/com/favoriteplace/global/auth/config/FeignClientConfig.java similarity index 95% rename from src/main/java/com/favoriteplace/global/security/config/FeignClientConfig.java rename to src/main/java/com/favoriteplace/global/auth/config/FeignClientConfig.java index 2549eb86..c5a39c78 100644 --- a/src/main/java/com/favoriteplace/global/security/config/FeignClientConfig.java +++ b/src/main/java/com/favoriteplace/global/auth/config/FeignClientConfig.java @@ -1,4 +1,4 @@ -package com.favoriteplace.global.security.config; +package com.favoriteplace.global.auth.config; import com.favoriteplace.global.exception.RestApiException; diff --git a/src/main/java/com/favoriteplace/global/security/config/JacksonConfig.java b/src/main/java/com/favoriteplace/global/auth/config/JacksonConfig.java similarity index 90% rename from src/main/java/com/favoriteplace/global/security/config/JacksonConfig.java rename to src/main/java/com/favoriteplace/global/auth/config/JacksonConfig.java index 878ed47e..41dff21f 100644 --- a/src/main/java/com/favoriteplace/global/security/config/JacksonConfig.java +++ b/src/main/java/com/favoriteplace/global/auth/config/JacksonConfig.java @@ -1,4 +1,4 @@ -package com.favoriteplace.global.security.config; +package com.favoriteplace.global.auth.config; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; diff --git a/src/main/java/com/favoriteplace/global/security/config/RedisConfig.java b/src/main/java/com/favoriteplace/global/auth/config/RedisConfig.java similarity index 92% rename from src/main/java/com/favoriteplace/global/security/config/RedisConfig.java rename to src/main/java/com/favoriteplace/global/auth/config/RedisConfig.java index 0e439cd2..713362fd 100644 --- a/src/main/java/com/favoriteplace/global/security/config/RedisConfig.java +++ b/src/main/java/com/favoriteplace/global/auth/config/RedisConfig.java @@ -1,4 +1,4 @@ -package com.favoriteplace.global.security.config; +package com.favoriteplace.global.auth.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -10,7 +10,6 @@ @Configuration public class RedisConfig { - // Bean 이름 지정 @Bean(name = "customRedisTemplate") public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate template = new RedisTemplate<>(); diff --git a/src/main/java/com/favoriteplace/global/security/config/SecurityConfig.java b/src/main/java/com/favoriteplace/global/auth/config/SecurityConfig.java similarity index 76% rename from src/main/java/com/favoriteplace/global/security/config/SecurityConfig.java rename to src/main/java/com/favoriteplace/global/auth/config/SecurityConfig.java index 8f217d7e..8819b133 100644 --- a/src/main/java/com/favoriteplace/global/security/config/SecurityConfig.java +++ b/src/main/java/com/favoriteplace/global/auth/config/SecurityConfig.java @@ -1,13 +1,13 @@ -package com.favoriteplace.global.security.config; - -import com.favoriteplace.global.security.filter.ExceptionHandlerFilter; -import com.favoriteplace.global.security.filter.JwtAuthenticationEntryPoint; -import com.favoriteplace.global.security.filter.JwtAuthenticationFilter; -import com.favoriteplace.global.security.filter.LoginFilter; -import com.favoriteplace.global.security.handler.CustomAuthenticationFailHandler; -import com.favoriteplace.global.security.handler.CustomAuthenticationSuccessHandler; -import com.favoriteplace.global.security.handler.JwtAccessDeniedHandler; -import com.favoriteplace.global.security.provider.JwtTokenProvider; +package com.favoriteplace.global.auth.config; + +import com.favoriteplace.global.auth.filter.ExceptionHandlerFilter; +import com.favoriteplace.global.auth.filter.JwtAuthenticationEntryPoint; +import com.favoriteplace.global.auth.filter.JwtAuthenticationFilter; +import com.favoriteplace.global.auth.filter.LoginFilter; +import com.favoriteplace.global.auth.handler.CustomAuthenticationFailHandler; +import com.favoriteplace.global.auth.handler.CustomAuthenticationSuccessHandler; +import com.favoriteplace.global.auth.handler.JwtAccessDeniedHandler; +import com.favoriteplace.global.auth.provider.JwtTokenProvider; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -31,9 +31,6 @@ public class SecurityConfig { private final JwtTokenProvider jwtTokenProvider; private final RedisTemplate redisTemplate; private final ExceptionHandlerFilter exceptionHandlerFilter; - - private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; - private final JwtAccessDeniedHandler jwtAccessDeniedHandler; private final AuthenticationManagerBuilder authManagerBuilder; private final CustomAuthenticationSuccessHandler successHandler; private final CustomAuthenticationFailHandler failureHandler; diff --git a/src/main/java/com/favoriteplace/global/security/filter/ExceptionHandlerFilter.java b/src/main/java/com/favoriteplace/global/auth/filter/ExceptionHandlerFilter.java similarity index 58% rename from src/main/java/com/favoriteplace/global/security/filter/ExceptionHandlerFilter.java rename to src/main/java/com/favoriteplace/global/auth/filter/ExceptionHandlerFilter.java index 980ee04e..4131c2f4 100644 --- a/src/main/java/com/favoriteplace/global/security/filter/ExceptionHandlerFilter.java +++ b/src/main/java/com/favoriteplace/global/auth/filter/ExceptionHandlerFilter.java @@ -1,18 +1,19 @@ -package com.favoriteplace.global.security.filter; +package com.favoriteplace.global.auth.filter; import com.fasterxml.jackson.databind.ObjectMapper; import com.favoriteplace.global.exception.ErrorCode; import com.favoriteplace.global.exception.ErrorResponse; import com.favoriteplace.global.exception.RestApiException; -import io.jsonwebtoken.ExpiredJwtException; -import io.jsonwebtoken.JwtException; + import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + import java.io.IOException; import lombok.extern.slf4j.Slf4j; + import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; @@ -22,36 +23,36 @@ public class ExceptionHandlerFilter extends OncePerRequestFilter { @Override protected void doFilterInternal( - HttpServletRequest request, - HttpServletResponse response, - FilterChain filterChain + HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain ) throws ServletException, IOException { - try{ + try { filterChain.doFilter(request, response); - }catch (ExpiredJwtException e){ - //토큰의 유효기간 만료 - log.info("토큰 유효기간 만료"); - setErrorResponse(response, ErrorCode.TOKEN_NOT_VALID); - }catch (JwtException | IllegalArgumentException e){ - //유효하지 않은 토큰 - log.info("유효하지 않은 토큰"); - setErrorResponse(response, ErrorCode.TOKEN_NOT_VALID); } catch (RestApiException e) { setErrorResponse(response, e.getErrorCode()); + log.warn("{}, uri: {}", e.getErrorCode().getMessage(), request.getRequestURI()); } } + private void setErrorResponse( - HttpServletResponse response, - ErrorCode errorCode - ){ + HttpServletResponse response, + ErrorCode errorCode + ) { ObjectMapper objectMapper = new ObjectMapper(); + response.setStatus(errorCode.getHttpStatus().value()); response.setContentType(MediaType.APPLICATION_JSON_VALUE); - com.favoriteplace.global.exception.ErrorResponse errorResponse = ErrorResponse.of(errorCode.getHttpStatus(), errorCode.getCode(), errorCode.getMessage()); - try{ + response.setCharacterEncoding("UTF-8"); + + ErrorResponse errorResponse = ErrorResponse.of( + errorCode.getHttpStatus(), errorCode.getCode(), errorCode.getMessage() + ); + + try { response.getWriter().write(objectMapper.writeValueAsString(errorResponse)); - }catch (IOException e){ + } catch (IOException e) { e.printStackTrace(); } } diff --git a/src/main/java/com/favoriteplace/global/security/filter/JwtAuthenticationEntryPoint.java b/src/main/java/com/favoriteplace/global/auth/filter/JwtAuthenticationEntryPoint.java similarity index 94% rename from src/main/java/com/favoriteplace/global/security/filter/JwtAuthenticationEntryPoint.java rename to src/main/java/com/favoriteplace/global/auth/filter/JwtAuthenticationEntryPoint.java index aa1aa0bc..e48f4aa9 100644 --- a/src/main/java/com/favoriteplace/global/security/filter/JwtAuthenticationEntryPoint.java +++ b/src/main/java/com/favoriteplace/global/auth/filter/JwtAuthenticationEntryPoint.java @@ -1,4 +1,4 @@ -package com.favoriteplace.global.security.filter; +package com.favoriteplace.global.auth.filter; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; diff --git a/src/main/java/com/favoriteplace/global/security/filter/LoginFilter.java b/src/main/java/com/favoriteplace/global/auth/filter/LoginFilter.java similarity index 85% rename from src/main/java/com/favoriteplace/global/security/filter/LoginFilter.java rename to src/main/java/com/favoriteplace/global/auth/filter/LoginFilter.java index 4a8a600e..b3ad7262 100644 --- a/src/main/java/com/favoriteplace/global/security/filter/LoginFilter.java +++ b/src/main/java/com/favoriteplace/global/auth/filter/LoginFilter.java @@ -1,8 +1,10 @@ -package com.favoriteplace.global.security.filter; +package com.favoriteplace.global.auth.filter; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + import lombok.RequiredArgsConstructor; + import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; @@ -15,13 +17,12 @@ public class LoginFilter extends UsernamePasswordAuthenticationFilter { @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) { - // 사용자가 제공한 인증 정보 추출 String email = request.getParameter("email"); String password = request.getParameter("password"); // UsernamePasswordAuthenticationToken 생성(이때 authentication 는 인증 여부를 확인하는 authenticated 값이 false) - UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken( - email, password); + UsernamePasswordAuthenticationToken authRequest = + new UsernamePasswordAuthenticationToken(email, password); /** * 실제 인증을 수행하도록 AuthenticationManager에게 위임 diff --git a/src/main/java/com/favoriteplace/global/security/handler/CustomAuthenticationFailHandler.java b/src/main/java/com/favoriteplace/global/auth/handler/CustomAuthenticationFailHandler.java similarity index 62% rename from src/main/java/com/favoriteplace/global/security/handler/CustomAuthenticationFailHandler.java rename to src/main/java/com/favoriteplace/global/auth/handler/CustomAuthenticationFailHandler.java index 6eb80b78..181bf7bb 100644 --- a/src/main/java/com/favoriteplace/global/security/handler/CustomAuthenticationFailHandler.java +++ b/src/main/java/com/favoriteplace/global/auth/handler/CustomAuthenticationFailHandler.java @@ -1,12 +1,15 @@ -package com.favoriteplace.global.security.handler; +package com.favoriteplace.global.auth.handler; import com.fasterxml.jackson.databind.ObjectMapper; + import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + import java.io.IOException; -import lombok.RequiredArgsConstructor; + import lombok.extern.slf4j.Slf4j; + import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.stereotype.Component; @@ -15,12 +18,15 @@ @Slf4j public class CustomAuthenticationFailHandler implements AuthenticationFailureHandler { @Override - public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, - AuthenticationException exception) throws IOException, ServletException { - log.warn("로그인 실패 | message : {}" , exception.getMessage()); + public void onAuthenticationFailure( + HttpServletRequest request, + HttpServletResponse response, + AuthenticationException exception + ) throws IOException, ServletException { + log.warn("로그인 실패 | message : {}", exception.getMessage()); String errorMessage = "login failed"; response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - new ObjectMapper().writeValue(response.getWriter(),errorMessage); + new ObjectMapper().writeValue(response.getWriter(), errorMessage); } } diff --git a/src/main/java/com/favoriteplace/global/security/handler/CustomAuthenticationSuccessHandler.java b/src/main/java/com/favoriteplace/global/auth/handler/CustomAuthenticationSuccessHandler.java similarity index 72% rename from src/main/java/com/favoriteplace/global/security/handler/CustomAuthenticationSuccessHandler.java rename to src/main/java/com/favoriteplace/global/auth/handler/CustomAuthenticationSuccessHandler.java index 875a0e36..9514497b 100644 --- a/src/main/java/com/favoriteplace/global/security/handler/CustomAuthenticationSuccessHandler.java +++ b/src/main/java/com/favoriteplace/global/auth/handler/CustomAuthenticationSuccessHandler.java @@ -1,22 +1,25 @@ -package com.favoriteplace.global.security.handler; +package com.favoriteplace.global.auth.handler; import static org.springframework.util.MimeTypeUtils.APPLICATION_JSON_VALUE; import com.fasterxml.jackson.databind.ObjectMapper; + import com.favoriteplace.app.domain.Member; -import com.favoriteplace.app.dto.member.MemberDto.TokenInfo; +import com.favoriteplace.app.dto.member.TokenInfoDto; import com.favoriteplace.app.repository.MemberRepository; -import com.favoriteplace.app.service.MemberService; import com.favoriteplace.global.exception.ErrorCode; import com.favoriteplace.global.exception.RestApiException; -import com.favoriteplace.global.security.provider.JwtTokenProvider; +import com.favoriteplace.global.auth.provider.JwtTokenProvider; + import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + import java.io.IOException; + import lombok.RequiredArgsConstructor; + import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -28,27 +31,20 @@ public class CustomAuthenticationSuccessHandler implements AuthenticationSuccess private final JwtTokenProvider jwtTokenProvider; private final MemberRepository memberRepository; - /** - * User - * - */ @Override @Transactional public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { - //유저 정보 가져오기 String email = request.getParameter("email"); Member member = memberRepository.findByEmail(email) .orElseThrow(() -> new RestApiException(ErrorCode.USER_NOT_FOUND)); - //인증 정보를 기반으로 JWT 토큰 생성 - response.setContentType(APPLICATION_JSON_VALUE); - TokenInfo tokenInfo = jwtTokenProvider.generateToken(member.getEmail()); + TokenInfoDto tokenInfo = jwtTokenProvider.generateToken(member.getEmail()); - //refreshToken 업데이트 - member.updateRefreshToken(tokenInfo.getRefreshToken()); + member.updateRefreshToken(tokenInfo.refreshToken()); + response.setContentType(APPLICATION_JSON_VALUE); new ObjectMapper().writeValue(response.getWriter(), tokenInfo); } } diff --git a/src/main/java/com/favoriteplace/global/security/handler/JwtAccessDeniedHandler.java b/src/main/java/com/favoriteplace/global/auth/handler/JwtAccessDeniedHandler.java similarity index 93% rename from src/main/java/com/favoriteplace/global/security/handler/JwtAccessDeniedHandler.java rename to src/main/java/com/favoriteplace/global/auth/handler/JwtAccessDeniedHandler.java index b00ff8f5..fba592ac 100644 --- a/src/main/java/com/favoriteplace/global/security/handler/JwtAccessDeniedHandler.java +++ b/src/main/java/com/favoriteplace/global/auth/handler/JwtAccessDeniedHandler.java @@ -1,4 +1,4 @@ -package com.favoriteplace.global.security.handler; +package com.favoriteplace.global.auth.handler; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; diff --git a/src/main/java/com/favoriteplace/global/security/kakao/KakaoClient.java b/src/main/java/com/favoriteplace/global/auth/kakao/KakaoClient.java similarity index 81% rename from src/main/java/com/favoriteplace/global/security/kakao/KakaoClient.java rename to src/main/java/com/favoriteplace/global/auth/kakao/KakaoClient.java index d550a9a6..6296ab78 100644 --- a/src/main/java/com/favoriteplace/global/security/kakao/KakaoClient.java +++ b/src/main/java/com/favoriteplace/global/auth/kakao/KakaoClient.java @@ -1,7 +1,7 @@ -package com.favoriteplace.global.security.kakao; +package com.favoriteplace.global.auth.kakao; import com.favoriteplace.app.dto.member.AuthKakaoLoginDto; -import com.favoriteplace.global.security.config.FeignClientConfig; +import com.favoriteplace.global.auth.config.FeignClientConfig; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestHeader; diff --git a/src/main/java/com/favoriteplace/global/auth/provider/JwtTokenProvider.java b/src/main/java/com/favoriteplace/global/auth/provider/JwtTokenProvider.java new file mode 100644 index 00000000..cf8f8522 --- /dev/null +++ b/src/main/java/com/favoriteplace/global/auth/provider/JwtTokenProvider.java @@ -0,0 +1,98 @@ +package com.favoriteplace.global.auth.provider; + +import com.favoriteplace.app.dto.member.TokenInfoDto; +import com.favoriteplace.global.exception.RestApiException; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.UnsupportedJwtException; +import io.jsonwebtoken.security.SignatureException; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.stereotype.Component; + +import static com.favoriteplace.global.exception.ErrorCode.INVALID_JWT; +import static com.favoriteplace.global.exception.ErrorCode.EXPIRED_JWT; +import static com.favoriteplace.global.exception.ErrorCode.INVALID_SIGNATURE; +import static com.favoriteplace.global.exception.ErrorCode.UNSUPPORTED_JWT; + +import java.util.Date; + +@Slf4j +@Component +@RequiredArgsConstructor +public class JwtTokenProvider { + + private static final Long ACCESS_TOKEN_EXPIRATION_TIME = 60 * 60 * 1000L; + private static final Long REFRESH_TOKEN_EXPIRATION_TIME = 24 * 60 * 60 * 1000L * 14; + + private final UserDetailsService userDetailsService; + + @Value("${jwt.secret}") + private String key; + + public TokenInfoDto generateToken(String userEmail) { + String accessToken = issueToken(userEmail, ACCESS_TOKEN_EXPIRATION_TIME); + String refreshToken = issueToken(userEmail, REFRESH_TOKEN_EXPIRATION_TIME); + + return TokenInfoDto.of(accessToken, refreshToken); + } + + public String issueToken(String userEmail, Long expirePeriod) { + Claims claims = Jwts.claims().setSubject(userEmail); + Date now = new Date(); + + String refreshToken = Jwts.builder() + .setClaims(claims) + .setIssuedAt(now) + .setExpiration(new Date(now.getTime() + expirePeriod)) + .signWith(SignatureAlgorithm.HS256, key) + .compact(); + + return refreshToken; + } + + public Authentication getAuthentication(String token) { + String userPrincipal = parseClaims(token).getSubject(); + + UserDetails userDetails = userDetailsService.loadUserByUsername(userPrincipal); + return new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword()); + } + + public Long getExpiration(String token) { + Date expiration = parseClaims(token).getExpiration(); + long now = new Date().getTime(); + + return (expiration.getTime() - now); + } + + public boolean validateToken(String token) { + try { + parseClaims(token); + return true; + } catch (MalformedJwtException e) { + throw new RestApiException(INVALID_JWT); + } catch (ExpiredJwtException e) { + throw new RestApiException(EXPIRED_JWT); + } catch (UnsupportedJwtException e) { + throw new RestApiException(UNSUPPORTED_JWT); + } catch (SignatureException e) { + throw new RestApiException(INVALID_SIGNATURE); + } + } + + private Claims parseClaims(String token) { + return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody(); + } + +} diff --git a/src/main/java/com/favoriteplace/global/security/service/CustomUserDetailsService.java b/src/main/java/com/favoriteplace/global/auth/service/CustomUserDetailsService.java similarity index 79% rename from src/main/java/com/favoriteplace/global/security/service/CustomUserDetailsService.java rename to src/main/java/com/favoriteplace/global/auth/service/CustomUserDetailsService.java index a2e96314..a0b1a462 100644 --- a/src/main/java/com/favoriteplace/global/security/service/CustomUserDetailsService.java +++ b/src/main/java/com/favoriteplace/global/auth/service/CustomUserDetailsService.java @@ -1,8 +1,10 @@ -package com.favoriteplace.global.security.service; +package com.favoriteplace.global.auth.service; import com.favoriteplace.app.domain.Member; import com.favoriteplace.app.repository.MemberRepository; + import lombok.RequiredArgsConstructor; + import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; @@ -18,13 +20,12 @@ public class CustomUserDetailsService implements UserDetailsService { private final PasswordEncoder passwordEncoder; @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - return memberRepository.findByEmail(username) + public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { + return memberRepository.findByEmail(email) .map(this::createUserDetails) .orElseThrow(() -> new UsernameNotFoundException("해당하는 유저를 찾을 수 없습니다.")); } - // 해당하는 User 의 데이터가 존재한다면 UserDetails 객체로 만들어서 리턴 private UserDetails createUserDetails(Member member) { return User.builder() .username(member.getEmail()) diff --git a/src/main/java/com/favoriteplace/global/exception/ErrorCode.java b/src/main/java/com/favoriteplace/global/exception/ErrorCode.java index ed8ced41..e50f7140 100644 --- a/src/main/java/com/favoriteplace/global/exception/ErrorCode.java +++ b/src/main/java/com/favoriteplace/global/exception/ErrorCode.java @@ -7,9 +7,7 @@ @Getter @RequiredArgsConstructor public enum ErrorCode { - /** - * 에러코드 자유롭게 추가 - */ + NOT_FOUND(HttpStatus.NOT_FOUND,404, "요청한 리소스를 찾을 수 없습니다."), INVALID_ARGUMENT_ERROR(HttpStatus.BAD_REQUEST, 400, "올바르지 않은 파라미터입니다."), INVALID_FORMAT_ERROR(HttpStatus.BAD_REQUEST,400, "올바르지 않은 포맷입니다."), @@ -18,6 +16,15 @@ public enum ErrorCode { INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 500, "서버 오류가 발생했습니다. 잠시 후 다시 시도해주세요."), INVALID_HTTP_METHOD(HttpStatus.METHOD_NOT_ALLOWED, 400, "잘못된 Http Method 요청입니다."), + //Auth (1000번대) + INVALID_JWT(HttpStatus.BAD_REQUEST, 1001, "잘못된 JWT 형식입니다."), + EXPIRED_JWT(HttpStatus.BAD_REQUEST, 1002, "만료된 JWT 토큰입니다."), + UNSUPPORTED_JWT(HttpStatus.BAD_REQUEST, 1003, "지원되지 않는 JWT 토큰입니다."), + INVALID_SIGNATURE(HttpStatus.BAD_REQUEST, 1004, "유효하지 않은 서명입니다."), + MISSING_AUTHORIZATION_JWT(HttpStatus.UNAUTHORIZED, 1005, "인증 토큰이 없습니다."), + INVALID_BEARER_PREFIX(HttpStatus.BAD_REQUEST, 1006, "Bearer 접두사가 누락되었습니다."), + + //User (2000번대) USER_NOT_FOUND(HttpStatus.BAD_REQUEST, 2001, "유저를 찾을 수 없습니다."), LOGIN_FAILED(HttpStatus.UNAUTHORIZED, 2002, "로그인에 실패했습니다."), diff --git a/src/main/java/com/favoriteplace/global/security/filter/JwtAuthenticationFilter.java b/src/main/java/com/favoriteplace/global/security/filter/JwtAuthenticationFilter.java deleted file mode 100644 index ebf2d564..00000000 --- a/src/main/java/com/favoriteplace/global/security/filter/JwtAuthenticationFilter.java +++ /dev/null @@ -1,155 +0,0 @@ -package com.favoriteplace.global.security.filter; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.favoriteplace.global.exception.ErrorCode; -import com.favoriteplace.global.exception.ErrorResponse; -import com.favoriteplace.global.exception.RestApiException; -import com.favoriteplace.global.security.provider.JwtTokenProvider; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.regex.Pattern; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; -import org.springframework.web.filter.OncePerRequestFilter; - -@RequiredArgsConstructor -@Slf4j -public class JwtAuthenticationFilter extends OncePerRequestFilter { - - private final JwtTokenProvider jwtTokenProvider; - private final RedisTemplate redisTemplate; - private final List excludePaths = Arrays.asList( - //인증이 필수인 경우 추가 - new ExcludePath("/auth/logout", HttpMethod.POST), - new ExcludePath("/pilgrimage/**", HttpMethod.POST), - new ExcludePath("/pilgrimage/**", HttpMethod.DELETE), - new ExcludePath("/posts/free/my-posts", HttpMethod.GET), - new ExcludePath("/posts/free/my-comments", HttpMethod.GET), - new ExcludePath("/posts/free", HttpMethod.POST), - new ExcludePath("/posts/free/**", HttpMethod.DELETE), - new ExcludePath("/posts/free/**", HttpMethod.POST), - new ExcludePath("/posts/free/**", HttpMethod.PUT), - new ExcludePath("/posts/free/**", HttpMethod.PATCH), - new ExcludePath("/posts/guestbooks/my-comments", HttpMethod.GET), - new ExcludePath("/posts/guestbooks/my-posts", HttpMethod.GET), - new ExcludePath("/my", HttpMethod.GET), - new ExcludePath("/my/**", HttpMethod.GET), - new ExcludePath("/my/**", HttpMethod.PUT), - new ExcludePath("/my/**", HttpMethod.PATCH), - new ExcludePath("/posts/guestbooks/**", HttpMethod.PATCH), - new ExcludePath("/posts/guestbooks/**", HttpMethod.DELETE), - new ExcludePath("/posts/guestbooks/**", HttpMethod.POST), - new ExcludePath("/my/blocks/**", HttpMethod.POST), - new ExcludePath("/posts/free/comments/**", HttpMethod.PUT), - new ExcludePath("/posts/free/comments/**", HttpMethod.DELETE), - new ExcludePath("/posts/guestbooks/comments/**", HttpMethod.PUT), - new ExcludePath("/posts/guestbooks/comments/**", HttpMethod.DELETE), - new ExcludePath("/shop/purchase/**", HttpMethod.POST), - new ExcludePath("/notifications", HttpMethod.PATCH), - new ExcludePath("/notifications", HttpMethod.GET), - new ExcludePath("/notifications/**", HttpMethod.PATCH), - new ExcludePath("/notifications/**", HttpMethod.DELETE) - // Add more paths and methods as needed - ); - - @Override - protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { - String requestURI = request.getServletPath(); - String method = request.getMethod(); - - return !excludePaths.stream() - .anyMatch(excludePath -> excludePath.matches(requestURI, method)); - } - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { - HttpServletRequest httpServletRequest = (HttpServletRequest) request; - - // 1. Request Header 에서 JWT 토큰 추출 - String token = resolveToken((HttpServletRequest) request); - - if ("websocket".equalsIgnoreCase(request.getHeader("Upgrade"))) { - chain.doFilter(request, response); - return; - } - - String requestURI = httpServletRequest.getRequestURI(); - - // 2. validateToken 으로 토큰 유효성 검사 - if (StringUtils.hasText(token) && token != null && jwtTokenProvider.validateToken(token)) { - /*1. Redis에 해당 accessToken logout 여부 확인 */ - String isLogout = (String) redisTemplate.opsForValue().get(token); - - if(!ObjectUtils.isEmpty(isLogout)) { - throw new RestApiException(ErrorCode.TOKEN_NOT_VALID); - } else { - /*2. 토큰이 유효할 경우 토큰에서 Authentication 객체를 가지고 와서 SecurityContext 에 저장 */ - Authentication authentication = jwtTokenProvider.getAuthentication(token); - SecurityContextHolder.getContext().setAuthentication(authentication); - log.info("Security Context에 '{}' 인증 정보를 저장했습니다, uri: {}", authentication.getName(), requestURI); - } - } else { - log.info("유효한 JWT 토큰이 없습니다, uri: {}", requestURI); - } - chain.doFilter(request, response); - } - - // Request Header 에서 토큰 정보 추출 - private String resolveToken(HttpServletRequest request) { - String bearerToken = request.getHeader("Authorization"); - - if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer")) { - return bearerToken.substring(7); - } - return null; - } - - public class ExcludePath { - private final String pathPattern; - private final HttpMethod method; - - public ExcludePath(String pathPattern, HttpMethod method) { - this.pathPattern = pathPattern; - this.method = method; - } - - public boolean matches(String requestURI, String method) { - // 정규 표현식을 사용하여 매치 여부 확인 - String regex = pathPattern.replaceAll("\\*\\*", ".*"); - return Pattern.matches(regex, requestURI) && this.method.matches(method); - } - } - - private enum HttpMethod { - GET, POST, PUT, DELETE, PATCH; // Add more methods as needed - - public boolean matches(String requestMethod) { - return this.name().equalsIgnoreCase(requestMethod); - } - } - - public void jwtExceptionHandler(HttpServletResponse response, ErrorCode errorCode) { - response.setStatus(errorCode.getCode()); - response.setContentType("application/json"); - response.setCharacterEncoding("UTF-8"); - try { - String json = new ObjectMapper().writeValueAsString(ErrorResponse.of(errorCode.getHttpStatus(), errorCode.getCode(), errorCode.getMessage())); - response.getOutputStream().write(json.getBytes()); - } catch (Exception e) { - log.error(e.getMessage()); - } - } - -} \ No newline at end of file diff --git a/src/main/java/com/favoriteplace/global/security/provider/JwtTokenProvider.java b/src/main/java/com/favoriteplace/global/security/provider/JwtTokenProvider.java deleted file mode 100644 index 09fa932c..00000000 --- a/src/main/java/com/favoriteplace/global/security/provider/JwtTokenProvider.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.favoriteplace.global.security.provider; - -import com.favoriteplace.app.dto.member.MemberDto.TokenInfo; -import com.favoriteplace.global.security.CustomUserDetails; -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.ExpiredJwtException; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.MalformedJwtException; -import io.jsonwebtoken.SignatureAlgorithm; -import io.jsonwebtoken.UnsupportedJwtException; -import io.jsonwebtoken.io.Decoders; -import io.jsonwebtoken.security.Keys; -import java.util.Date; -import java.util.List; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.stereotype.Component; - -@Slf4j -@Component -@RequiredArgsConstructor -public class JwtTokenProvider { - @Value("${jwt.secret}") - private String key; - private final Long accessExpirePeriod = 24 * 60 * 60 * 1000L * 30; - private final Long refreshExpirePeriod = 24 * 60 * 60 * 1000L * 40; - private final UserDetailsService userDetailsService; - - public TokenInfo generateToken(String userEmail) { - Claims claims = Jwts.claims().setSubject(userEmail); - Date now = new Date(); - - // Access Token 생성 - String accessToken = Jwts.builder() - .setClaims(claims) - .setIssuedAt(now) - .setExpiration(new Date(now.getTime() + accessExpirePeriod)) - .signWith(SignatureAlgorithm.HS256, key) - .compact(); - - // Refresh Token 생성 - String refreshToken = createRefreshToken(userEmail); - return TokenInfo.builder() - .grantType("Bearer") - .accessToken(accessToken) - .refreshToken(refreshToken) - .build(); - } - - public String createRefreshToken(String userEmail){ - Claims claims = Jwts.claims().setSubject(userEmail); - Date now = new Date(); - - String refreshToken = Jwts.builder() - .setClaims(claims) - .setIssuedAt(now) - .setExpiration(new Date(now.getTime() + refreshExpirePeriod)) - .signWith(SignatureAlgorithm.HS256, key) - .compact(); - - return refreshToken; - } - - // JWT 토큰을 복호화하여 토큰에 들어있는 정보를 꺼내는 메서드 - public Authentication getAuthentication(String accessToken) { - String userPrincipal = Jwts.parser(). - setSigningKey(key) - .parseClaimsJws(accessToken) - .getBody().getSubject(); - UserDetails userDetails = userDetailsService.loadUserByUsername(userPrincipal); - - return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities()); - } - - public Long getExpiration(String accessToken) { - Date expiration = Jwts.parserBuilder().setSigningKey(key) - .build().parseClaimsJws(accessToken).getBody().getExpiration(); - - long now = new Date().getTime(); - - return (expiration.getTime() - now); - } - - // 토큰 정보를 검증하는 메서드 - public boolean validateToken(String token) { - try { - Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token); - return true; - } catch (io.jsonwebtoken.security.SecurityException | MalformedJwtException e) { - log.info("Invalid JWT Token", e); - } catch (ExpiredJwtException e) { - log.info("Expired JWT Token", e); - } catch (UnsupportedJwtException e) { - log.info("Unsupported JWT Token", e); - } catch (IllegalArgumentException e) { - log.info("JWT claims string is empty.", e); - } - return false; - } - - private Claims parseClaims(String accessToken) { - try { - return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(accessToken).getBody(); - } catch (ExpiredJwtException e) { - return e.getClaims(); - } - } -} diff --git a/src/main/java/com/favoriteplace/global/util/SecurityUtil.java b/src/main/java/com/favoriteplace/global/util/SecurityUtil.java index eae6874a..36f295d8 100644 --- a/src/main/java/com/favoriteplace/global/util/SecurityUtil.java +++ b/src/main/java/com/favoriteplace/global/util/SecurityUtil.java @@ -2,9 +2,7 @@ import com.favoriteplace.app.domain.Member; import com.favoriteplace.app.repository.MemberRepository; -import com.favoriteplace.global.exception.ErrorCode; -import com.favoriteplace.global.exception.RestApiException; -import com.favoriteplace.global.security.provider.JwtTokenProvider; +import com.favoriteplace.global.auth.provider.JwtTokenProvider; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.security.core.Authentication; diff --git a/src/main/java/com/favoriteplace/global/websocket/JwtChannelInterceptor.java b/src/main/java/com/favoriteplace/global/websocket/JwtChannelInterceptor.java index d46a94fd..1785b907 100644 --- a/src/main/java/com/favoriteplace/global/websocket/JwtChannelInterceptor.java +++ b/src/main/java/com/favoriteplace/global/websocket/JwtChannelInterceptor.java @@ -3,11 +3,9 @@ import com.favoriteplace.app.domain.Member; import com.favoriteplace.app.repository.MemberRepository; import com.favoriteplace.global.exception.ErrorCode; -import com.favoriteplace.global.exception.ErrorResponse; import com.favoriteplace.global.exception.RestApiException; -import com.favoriteplace.global.security.CustomUserDetails; -import com.favoriteplace.global.security.provider.JwtTokenProvider; -import com.google.api.gax.rpc.ApiException; +import com.favoriteplace.global.auth.CustomUserDetails; +import com.favoriteplace.global.auth.provider.JwtTokenProvider; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.Ordered; @@ -17,10 +15,8 @@ import org.springframework.messaging.simp.stomp.StompCommand; import org.springframework.messaging.simp.stomp.StompHeaderAccessor; import org.springframework.messaging.support.ChannelInterceptor; -import org.springframework.messaging.support.MessageHeaderAccessor; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import java.util.List; From cfdad22f7097bfa45ba92aaebe5d961024800b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9C=A4?= Date: Thu, 16 Jan 2025 01:24:06 +0900 Subject: [PATCH 6/9] =?UTF-8?q?[refactor]=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filter/JwtAuthenticationEntryPoint.java | 22 ------------------- .../auth/handler/JwtAccessDeniedHandler.java | 21 ------------------ 2 files changed, 43 deletions(-) delete mode 100644 src/main/java/com/favoriteplace/global/auth/filter/JwtAuthenticationEntryPoint.java delete mode 100644 src/main/java/com/favoriteplace/global/auth/handler/JwtAccessDeniedHandler.java diff --git a/src/main/java/com/favoriteplace/global/auth/filter/JwtAuthenticationEntryPoint.java b/src/main/java/com/favoriteplace/global/auth/filter/JwtAuthenticationEntryPoint.java deleted file mode 100644 index e48f4aa9..00000000 --- a/src/main/java/com/favoriteplace/global/auth/filter/JwtAuthenticationEntryPoint.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.favoriteplace.global.auth.filter; - -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.stereotype.Component; - -/** - * 유효한 자격증명을 제공하지 않고 접근하려 할때 401 Unauthorized 에러를 리턴하는 class - */ -@Component -public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { - @Override - public void commence(HttpServletRequest request, - HttpServletResponse response, - AuthenticationException authException) throws IOException { - // 유효한 자격증명을 제공하지 않고 접근하려 할때 401 - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); - } -} diff --git a/src/main/java/com/favoriteplace/global/auth/handler/JwtAccessDeniedHandler.java b/src/main/java/com/favoriteplace/global/auth/handler/JwtAccessDeniedHandler.java deleted file mode 100644 index fba592ac..00000000 --- a/src/main/java/com/favoriteplace/global/auth/handler/JwtAccessDeniedHandler.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.favoriteplace.global.auth.handler; - -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.web.access.AccessDeniedHandler; -import org.springframework.stereotype.Component; - -/** - * 필요한 권한이 존재하지 않는 겨경우에 403 Forbidden 에러를 리턴하는 class - */ -@Component -public class JwtAccessDeniedHandler implements AccessDeniedHandler { - @Override - public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) - throws IOException { - //필요한 권한이 없이 접근하려 할때 403 - response.sendError(HttpServletResponse.SC_FORBIDDEN); - } -} \ No newline at end of file From c5337b150857bb3c26ea7f94ee6da3f24d35a2a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9C=A4?= Date: Thu, 16 Jan 2025 15:03:44 +0900 Subject: [PATCH 7/9] =?UTF-8?q?[feat]=20UserEmailResolver=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/controller/ShopController.java | 6 ++- .../global/auth/config/SecurityConfig.java | 4 +- .../global/auth/resolver/UserEmail.java | 12 ++++++ .../auth/resolver/UserEmailResolver.java | 39 +++++++++++++++++++ .../global/config/WebConfig.java | 21 ++++++++++ 5 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/favoriteplace/global/auth/resolver/UserEmail.java create mode 100644 src/main/java/com/favoriteplace/global/auth/resolver/UserEmailResolver.java create mode 100644 src/main/java/com/favoriteplace/global/config/WebConfig.java diff --git a/src/main/java/com/favoriteplace/app/controller/ShopController.java b/src/main/java/com/favoriteplace/app/controller/ShopController.java index 3beb127b..9a5a4294 100644 --- a/src/main/java/com/favoriteplace/app/controller/ShopController.java +++ b/src/main/java/com/favoriteplace/app/controller/ShopController.java @@ -2,6 +2,7 @@ import com.favoriteplace.app.dto.item.ItemDto; import com.favoriteplace.app.service.ShopService; +import com.favoriteplace.global.auth.resolver.UserEmail; import com.favoriteplace.global.util.SecurityUtil; import jakarta.servlet.http.HttpServletRequest; @@ -45,7 +46,10 @@ public ResponseEntity getItemDetail( } @PostMapping("/purchase/{item_id}") - public ResponseEntity buyItem(@PathVariable("item_id") Long itemId) { + public ResponseEntity buyItem( + @PathVariable("item_id") Long itemId, + @UserEmail String userEmail + ) { return ResponseEntity.ok(shopService.buyItem(itemId)); } } diff --git a/src/main/java/com/favoriteplace/global/auth/config/SecurityConfig.java b/src/main/java/com/favoriteplace/global/auth/config/SecurityConfig.java index 8819b133..41d70f3c 100644 --- a/src/main/java/com/favoriteplace/global/auth/config/SecurityConfig.java +++ b/src/main/java/com/favoriteplace/global/auth/config/SecurityConfig.java @@ -1,14 +1,14 @@ package com.favoriteplace.global.auth.config; import com.favoriteplace.global.auth.filter.ExceptionHandlerFilter; -import com.favoriteplace.global.auth.filter.JwtAuthenticationEntryPoint; import com.favoriteplace.global.auth.filter.JwtAuthenticationFilter; import com.favoriteplace.global.auth.filter.LoginFilter; import com.favoriteplace.global.auth.handler.CustomAuthenticationFailHandler; import com.favoriteplace.global.auth.handler.CustomAuthenticationSuccessHandler; -import com.favoriteplace.global.auth.handler.JwtAccessDeniedHandler; import com.favoriteplace.global.auth.provider.JwtTokenProvider; + import lombok.RequiredArgsConstructor; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.RedisTemplate; diff --git a/src/main/java/com/favoriteplace/global/auth/resolver/UserEmail.java b/src/main/java/com/favoriteplace/global/auth/resolver/UserEmail.java new file mode 100644 index 00000000..282393bb --- /dev/null +++ b/src/main/java/com/favoriteplace/global/auth/resolver/UserEmail.java @@ -0,0 +1,12 @@ +package com.favoriteplace.global.auth.resolver; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface UserEmail { +} + diff --git a/src/main/java/com/favoriteplace/global/auth/resolver/UserEmailResolver.java b/src/main/java/com/favoriteplace/global/auth/resolver/UserEmailResolver.java new file mode 100644 index 00000000..ebf8930d --- /dev/null +++ b/src/main/java/com/favoriteplace/global/auth/resolver/UserEmailResolver.java @@ -0,0 +1,39 @@ +package com.favoriteplace.global.auth.resolver; + +import com.favoriteplace.global.auth.provider.JwtTokenProvider; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.constraints.NotNull; + +import lombok.RequiredArgsConstructor; + +import org.springframework.core.MethodParameter; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.ModelAndViewContainer; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; + + +@Component +public class UserEmailResolver implements HandlerMethodArgumentResolver { + + @Override + public boolean supportsParameter(MethodParameter parameter) { + //UserEmail annotaion을 붙였는지, parameter 타입이 String 타입인지 확인 + return parameter.hasParameterAnnotation(UserEmail.class) && String.class.equals(parameter.getParameterType()); + } + + @Override + public String resolveArgument( + MethodParameter parameter, + ModelAndViewContainer modelAndViewContainer, + NativeWebRequest webRequest, + WebDataBinderFactory binderFactory + ) { + return SecurityContextHolder.getContext() + .getAuthentication().getName(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/favoriteplace/global/config/WebConfig.java b/src/main/java/com/favoriteplace/global/config/WebConfig.java new file mode 100644 index 00000000..374d62de --- /dev/null +++ b/src/main/java/com/favoriteplace/global/config/WebConfig.java @@ -0,0 +1,21 @@ +package com.favoriteplace.global.config; + +import com.favoriteplace.global.auth.resolver.UserEmailResolver; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.List; + +@Configuration +@RequiredArgsConstructor +public class WebConfig implements WebMvcConfigurer { + + private final UserEmailResolver userEmailResolver; + + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(userEmailResolver); + } +} \ No newline at end of file From 59e00fa4634982e8ee0f2d3622cc0eed5346762a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9C=A4?= Date: Thu, 16 Jan 2025 15:04:42 +0900 Subject: [PATCH 8/9] =?UTF-8?q?[refactor]=20JwtTokenProvider=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 명확한 의미전달을 위해 변수명을 수정했습니다. --- .../favoriteplace/global/auth/provider/JwtTokenProvider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/favoriteplace/global/auth/provider/JwtTokenProvider.java b/src/main/java/com/favoriteplace/global/auth/provider/JwtTokenProvider.java index cf8f8522..01bab7c5 100644 --- a/src/main/java/com/favoriteplace/global/auth/provider/JwtTokenProvider.java +++ b/src/main/java/com/favoriteplace/global/auth/provider/JwtTokenProvider.java @@ -63,9 +63,9 @@ public String issueToken(String userEmail, Long expirePeriod) { } public Authentication getAuthentication(String token) { - String userPrincipal = parseClaims(token).getSubject(); + String userEmail = parseClaims(token).getSubject(); - UserDetails userDetails = userDetailsService.loadUserByUsername(userPrincipal); + UserDetails userDetails = userDetailsService.loadUserByUsername(userEmail); return new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword()); } From 178865044320925b9f7cc74eaf34716ab3b12761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9C=A4?= Date: Thu, 16 Jan 2025 16:24:18 +0900 Subject: [PATCH 9/9] =?UTF-8?q?[fix]=20UserEmailResolver=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=EC=9D=B4=20=ED=95=84=EC=88=98=EA=B0=80=20=EC=95=84?= =?UTF-8?q?=EB=8B=8C=20=EA=B2=BD=EC=9A=B0=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/controller/ShopController.java | 3 ++- .../auth/filter/JwtAuthenticationFilter.java | 3 --- .../auth/resolver/UserEmailResolver.java | 24 +++++++++++++++++-- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/favoriteplace/app/controller/ShopController.java b/src/main/java/com/favoriteplace/app/controller/ShopController.java index 9a5a4294..dcf929c6 100644 --- a/src/main/java/com/favoriteplace/app/controller/ShopController.java +++ b/src/main/java/com/favoriteplace/app/controller/ShopController.java @@ -34,7 +34,8 @@ public ResponseEntity getAlwaysSellProduct(HttpServletRe } @GetMapping("/new") - public ResponseEntity getNewItemList() { + public ResponseEntity getNewItemList(@UserEmail String email) { + System.out.println("email = " + email); return ResponseEntity.ok(shopService.getNewItemList()); } diff --git a/src/main/java/com/favoriteplace/global/auth/filter/JwtAuthenticationFilter.java b/src/main/java/com/favoriteplace/global/auth/filter/JwtAuthenticationFilter.java index a64b0af0..d7bc1079 100644 --- a/src/main/java/com/favoriteplace/global/auth/filter/JwtAuthenticationFilter.java +++ b/src/main/java/com/favoriteplace/global/auth/filter/JwtAuthenticationFilter.java @@ -11,9 +11,6 @@ import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.regex.Pattern; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/com/favoriteplace/global/auth/resolver/UserEmailResolver.java b/src/main/java/com/favoriteplace/global/auth/resolver/UserEmailResolver.java index ebf8930d..51b8428c 100644 --- a/src/main/java/com/favoriteplace/global/auth/resolver/UserEmailResolver.java +++ b/src/main/java/com/favoriteplace/global/auth/resolver/UserEmailResolver.java @@ -7,9 +7,12 @@ import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.core.MethodParameter; +import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.ModelAndViewContainer; @@ -17,8 +20,12 @@ @Component +@Slf4j +@RequiredArgsConstructor public class UserEmailResolver implements HandlerMethodArgumentResolver { + private final JwtTokenProvider jwtTokenProvider; + @Override public boolean supportsParameter(MethodParameter parameter) { //UserEmail annotaion을 붙였는지, parameter 타입이 String 타입인지 확인 @@ -32,8 +39,21 @@ public String resolveArgument( NativeWebRequest webRequest, WebDataBinderFactory binderFactory ) { - return SecurityContextHolder.getContext() - .getAuthentication().getName(); + HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest(); + + String userEmail = SecurityContextHolder.getContext().getAuthentication().getName(); + + if(userEmail.equals("anonymousUser")) { + String bearerToken = request.getHeader("Authorization"); + if(bearerToken == null) { + return null; + } + String token = bearerToken.substring(7); + jwtTokenProvider.validateToken(token); + Authentication authentication = jwtTokenProvider.getAuthentication(token); + return authentication.getName(); + } + return userEmail; } } \ No newline at end of file