From cdddc7153f16bd26fac3a7c161d347a0b63bb3af Mon Sep 17 00:00:00 2001 From: cjsqudwns Date: Tue, 15 Jul 2025 11:18:33 +0900 Subject: [PATCH 1/9] =?UTF-8?q?cd:=20test=EC=9A=A9=20branch=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a534a92..678e550 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -6,6 +6,7 @@ on: - dev - ci/* - cd/* + - fix/test/* workflow_dispatch: jobs: @@ -83,7 +84,7 @@ jobs: env: SHORT_SHA: ${{ needs.ci.outputs.short_sha }} - DEPLOY_BRANCH: dev + DEPLOY_BRANCH: test-backend steps: - name: Clone team2-infra repository From 814c95c640bd3585b8fd50df65f43ae533c6e6fb Mon Sep 17 00:00:00 2001 From: cjsqudwns Date: Tue, 15 Jul 2025 11:24:57 +0900 Subject: [PATCH 2/9] =?UTF-8?q?fix:=20Cors=20=EC=84=A4=EC=A0=95=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 --- .../config/security/SecurityConfig.java | 61 +++++++++++++------ 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/bootcamp/savemypodo/config/security/SecurityConfig.java b/src/main/java/com/bootcamp/savemypodo/config/security/SecurityConfig.java index b8fe577..72903f4 100644 --- a/src/main/java/com/bootcamp/savemypodo/config/security/SecurityConfig.java +++ b/src/main/java/com/bootcamp/savemypodo/config/security/SecurityConfig.java @@ -9,9 +9,12 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import java.util.List; @@ -25,43 +28,65 @@ public class SecurityConfig { @Value("${frontend.url}") private String frontendUrl; - @Value("${backend.url}") - private String backendUrl; + + private final String[] allowUrls = { + "/", "/favicon.ico", "/actuator/**", "/api/auth/**", "/login/**", "/error", "/oauth/**" + }; + + @Bean + public WebSecurityCustomizer configure() { + return web -> web.ignoring().requestMatchers(allowUrls); + } @Bean - public SecurityFilterChain filterChain(HttpSecurity http, OAuth2SuccessHandler oAuth2SuccessHandler, OAuth2FailureHandler oAuth2FailureHandler, + public SecurityFilterChain filterChain(HttpSecurity http, + OAuth2SuccessHandler oAuth2SuccessHandler, + OAuth2FailureHandler oAuth2FailureHandler, JwtAuthenticationFilter jwtAuthenticationFilter) throws Exception { log.info("[SecurityConfig]: 진입"); - http - .cors(cors -> cors.configurationSource(request -> { - CorsConfiguration config = new CorsConfiguration(); - config.setAllowedOrigins(List.of(frontendUrl)); // 프론트 주소 - config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS")); - config.setAllowedHeaders(List.of("*")); - config.setAllowCredentials(true); - return config; - })) + http + .cors(cors -> cors.configurationSource(corsConfigurationSource())) .csrf(csrf -> csrf.disable()) - .authorizeHttpRequests(auth -> auth .requestMatchers("/", "/login", "/api/musicals", "/actuator/prometheus", "/api/user/me").permitAll() .requestMatchers("/api/admin/**").hasRole("ADMIN") .requestMatchers("/api/user/**", "/api/reservations/**", "/api/musicals/**").hasRole("USER") .anyRequest().authenticated() ) - .oauth2Login(oauth2 -> oauth2 - .userInfoEndpoint(userInfo -> userInfo - .userService(customOAuth2UserService) - ) + .userInfoEndpoint(userInfo -> userInfo.userService(customOAuth2UserService)) .successHandler(oAuth2SuccessHandler) .failureHandler(oAuth2FailureHandler) ) .logout(logout -> logout.disable()) - .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); } + + /** + * ✅ Cors 설정 분리 - Credentials + Exposed Headers 등 명시 + */ + @Bean + public CorsConfigurationSource corsConfigurationSource() { + CorsConfiguration configuration = new CorsConfiguration(); + configuration.setAllowedOrigins(List.of(frontendUrl)); + configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS")); + configuration.setAllowedHeaders(List.of( + "Authorization", + "Content-Type", + "X-Requested-With", + "social_access_token" + )); + configuration.setExposedHeaders(List.of( + "Authorization", + "Set-Cookie" + )); + configuration.setAllowCredentials(true); + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", configuration); + return source; + } } \ No newline at end of file From 16a45c5a8b868feebc147fdb92aabbe4e61cfffb Mon Sep 17 00:00:00 2001 From: cjsqudwns Date: Tue, 15 Jul 2025 11:38:47 +0900 Subject: [PATCH 3/9] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=20web.ignoring=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/bootcamp/savemypodo/config/security/SecurityConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/bootcamp/savemypodo/config/security/SecurityConfig.java b/src/main/java/com/bootcamp/savemypodo/config/security/SecurityConfig.java index 72903f4..0883e02 100644 --- a/src/main/java/com/bootcamp/savemypodo/config/security/SecurityConfig.java +++ b/src/main/java/com/bootcamp/savemypodo/config/security/SecurityConfig.java @@ -30,7 +30,7 @@ public class SecurityConfig { private String frontendUrl; private final String[] allowUrls = { - "/", "/favicon.ico", "/actuator/**", "/api/auth/**", "/login/**", "/error", "/oauth/**" + "/", "/favicon.ico", "/actuator/**", "/api/auth/**", "/error", "/oauth/**" }; @Bean From 23aaed27ec37400b3471a441fe9855cc5284e816 Mon Sep 17 00:00:00 2001 From: cjsqudwns Date: Tue, 15 Jul 2025 11:45:24 +0900 Subject: [PATCH 4/9] =?UTF-8?q?fix:=20jwtTokenProvider=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9E=90=20=EC=A3=BC=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bootcamp/savemypodo/config/security/utils/CookieUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/bootcamp/savemypodo/config/security/utils/CookieUtil.java b/src/main/java/com/bootcamp/savemypodo/config/security/utils/CookieUtil.java index 0e8d5c2..70eaca4 100644 --- a/src/main/java/com/bootcamp/savemypodo/config/security/utils/CookieUtil.java +++ b/src/main/java/com/bootcamp/savemypodo/config/security/utils/CookieUtil.java @@ -12,7 +12,7 @@ @RequiredArgsConstructor public class CookieUtil { - JwtTokenProvider jwtTokenProvider; + private final JwtTokenProvider jwtTokenProvider; // ✅ 공통 쿠키 생성 유틸 public Cookie createCookie(String type, String token) { From 86a58fd194bc3a54af0ae68309a7443dd3c4915b Mon Sep 17 00:00:00 2001 From: cjsqudwns Date: Tue, 15 Jul 2025 12:28:25 +0900 Subject: [PATCH 5/9] =?UTF-8?q?fix:=20cookie.setDomain=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bootcamp/savemypodo/config/security/utils/CookieUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/bootcamp/savemypodo/config/security/utils/CookieUtil.java b/src/main/java/com/bootcamp/savemypodo/config/security/utils/CookieUtil.java index 70eaca4..880c2b2 100644 --- a/src/main/java/com/bootcamp/savemypodo/config/security/utils/CookieUtil.java +++ b/src/main/java/com/bootcamp/savemypodo/config/security/utils/CookieUtil.java @@ -30,7 +30,7 @@ public Cookie createCookie(String type, String token) { cookie.setSecure(true); cookie.setPath("/"); cookie.setMaxAge((int) (expirationTime / 1000)); - cookie.setDomain(".savemypodo.shop"); // 하위 도메인까지 허용 +// cookie.setDomain(".savemypodo.shop"); // 하위 도메인까지 허용 cookie.setAttribute("SameSite", "None"); // CORS 허용 return cookie; From bca1bb1686f97c8fc9374a234d125f61d4ac6848 Mon Sep 17 00:00:00 2001 From: cjsqudwns Date: Tue, 15 Jul 2025 13:05:39 +0900 Subject: [PATCH 6/9] =?UTF-8?q?refactor:=20=EC=9D=B4=EC=A0=84=20/user/my-r?= =?UTF-8?q?eservations=20=EA=B4=80=EB=A0=A8=20=EB=A6=AC=EC=86=8C=EC=8A=A4?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bootcamp/savemypodo/controller/UserController.java | 10 ---------- .../savemypodo/service/ReservationService.java | 8 -------- 2 files changed, 18 deletions(-) diff --git a/src/main/java/com/bootcamp/savemypodo/controller/UserController.java b/src/main/java/com/bootcamp/savemypodo/controller/UserController.java index 2cbb0bd..2b1ce66 100644 --- a/src/main/java/com/bootcamp/savemypodo/controller/UserController.java +++ b/src/main/java/com/bootcamp/savemypodo/controller/UserController.java @@ -1,7 +1,6 @@ package com.bootcamp.savemypodo.controller; import com.bootcamp.savemypodo.config.security.utils.CookieUtil; -import com.bootcamp.savemypodo.dto.reservation.MyReservationResponse; import com.bootcamp.savemypodo.dto.user.UserResponse; import com.bootcamp.savemypodo.entity.User; import com.bootcamp.savemypodo.global.exception.ErrorCode; @@ -22,8 +21,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - @Slf4j @RestController @RequestMapping("/api/user") @@ -82,11 +79,4 @@ public ResponseEntity getMyInfo(@AuthenticationPrincipal User user return ResponseEntity.ok(userResponse); } - - @GetMapping("/my-reservations") - public ResponseEntity> getMyReservations(@AuthenticationPrincipal User user) { - List myReservations = reservationService.getMyReservationsByUser(user); - return ResponseEntity.ok(myReservations); - } - } diff --git a/src/main/java/com/bootcamp/savemypodo/service/ReservationService.java b/src/main/java/com/bootcamp/savemypodo/service/ReservationService.java index f142538..cb61129 100644 --- a/src/main/java/com/bootcamp/savemypodo/service/ReservationService.java +++ b/src/main/java/com/bootcamp/savemypodo/service/ReservationService.java @@ -1,6 +1,5 @@ package com.bootcamp.savemypodo.service; -import com.bootcamp.savemypodo.dto.reservation.MyReservationResponse; import com.bootcamp.savemypodo.entity.Musical; import com.bootcamp.savemypodo.entity.Reservation; import com.bootcamp.savemypodo.entity.Seat; @@ -18,10 +17,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.util.List; import java.util.NoSuchElementException; import java.util.Optional; -import java.util.stream.Collectors; @Slf4j @Service @@ -73,11 +70,6 @@ public void createReservation(User user, Long mid, String seatName) { } - public List getMyReservationsByUser(User user) { - List reservations = reservationRepository.findAllByUser(user); - return reservations.stream().map(MyReservationResponse::fromEntity).collect(Collectors.toList()); - } - @Transactional public void cancelReservation(Long userId, Long musicalId) { // 1. 먼저 예약이 실제로 존재하는지 확인 From e5247e84c87ce247064259996229fae34baeef30 Mon Sep 17 00:00:00 2001 From: cjsqudwns Date: Tue, 15 Jul 2025 13:18:30 +0900 Subject: [PATCH 7/9] =?UTF-8?q?fix:=20ALB=20=EB=B0=8F=20Prometheus=20?= =?UTF-8?q?=ED=97=AC=EC=8A=A4=EC=B2=B4=ED=81=AC=20=EA=B2=BD=EB=A1=9C(/)=20?= =?UTF-8?q?=EB=8C=80=EC=9D=91=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=20=EB=A1=9C=EA=B7=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/jwt/JwtAuthenticationFilter.java | 7 ++----- .../savemypodo/controller/HealthController.java | 13 +++++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/bootcamp/savemypodo/controller/HealthController.java diff --git a/src/main/java/com/bootcamp/savemypodo/config/jwt/JwtAuthenticationFilter.java b/src/main/java/com/bootcamp/savemypodo/config/jwt/JwtAuthenticationFilter.java index f114430..197ebc1 100644 --- a/src/main/java/com/bootcamp/savemypodo/config/jwt/JwtAuthenticationFilter.java +++ b/src/main/java/com/bootcamp/savemypodo/config/jwt/JwtAuthenticationFilter.java @@ -36,11 +36,10 @@ protected void doFilterInternal(HttpServletRequest request, throws ServletException, IOException { String uri = request.getRequestURI(); - log.info("🔍 [JWT 필터] 시작: {}", uri); + + // 여기 경로는 Jwt Filter 무시 if (uri.equals("/") || uri.startsWith("/login") || uri.equals("/api/musicals") || uri.equals("/actuator/prometheus") || uri.equals("/api/user/me")) { filterChain.doFilter(request, response); // 그냥 통과 - /*if (uri.equals("/") || uri.startsWith("/login") || uri.equals("/api/musicals")) { - filterChain.doFilter(request, response);*/ return; } @@ -48,8 +47,6 @@ protected void doFilterInternal(HttpServletRequest request, String refreshToken = cookieUtil.getTokenFromCookie(request, "refreshToken"); log.info("🔍 [JWT 필터] 요청 URI: {}", uri); - log.info("🔑 accessToken 존재 여부: {}", accessToken != null); - log.info("🔑 refreshToken 존재 여부: {}", refreshToken != null); try { if (accessToken != null && jwtTokenProvider.validateToken(accessToken)) { diff --git a/src/main/java/com/bootcamp/savemypodo/controller/HealthController.java b/src/main/java/com/bootcamp/savemypodo/controller/HealthController.java new file mode 100644 index 0000000..d2bc0b0 --- /dev/null +++ b/src/main/java/com/bootcamp/savemypodo/controller/HealthController.java @@ -0,0 +1,13 @@ +package com.bootcamp.savemypodo.controller; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HealthController { + @GetMapping("/") + public ResponseEntity health() { + return ResponseEntity.ok("OK"); + } +} From dd8c37c65c47cafdebb00d2795147a19640e0a14 Mon Sep 17 00:00:00 2001 From: cjsqudwns Date: Tue, 15 Jul 2025 14:01:17 +0900 Subject: [PATCH 8/9] =?UTF-8?q?fix:=20=EA=B2=BD=EB=A1=9C=20'/api/user/me'?= =?UTF-8?q?=20JWT=20=EC=9D=B8=EC=A6=9D=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bootcamp/savemypodo/config/jwt/JwtAuthenticationFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/bootcamp/savemypodo/config/jwt/JwtAuthenticationFilter.java b/src/main/java/com/bootcamp/savemypodo/config/jwt/JwtAuthenticationFilter.java index 197ebc1..eb4cbae 100644 --- a/src/main/java/com/bootcamp/savemypodo/config/jwt/JwtAuthenticationFilter.java +++ b/src/main/java/com/bootcamp/savemypodo/config/jwt/JwtAuthenticationFilter.java @@ -38,7 +38,7 @@ protected void doFilterInternal(HttpServletRequest request, String uri = request.getRequestURI(); // 여기 경로는 Jwt Filter 무시 - if (uri.equals("/") || uri.startsWith("/login") || uri.equals("/api/musicals") || uri.equals("/actuator/prometheus") || uri.equals("/api/user/me")) { + if (uri.equals("/") || uri.startsWith("/login") || uri.equals("/api/musicals") || uri.equals("/actuator/prometheus")) { filterChain.doFilter(request, response); // 그냥 통과 return; } From b2f1f6d59d4643142c782ebae197df920c19f554 Mon Sep 17 00:00:00 2001 From: cjsqudwns Date: Tue, 15 Jul 2025 14:18:33 +0900 Subject: [PATCH 9/9] =?UTF-8?q?chore:=20CD=20=EB=B8=8C=EB=9E=9C=EC=B9=98?= =?UTF-8?q?=20'dev'=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20(=EC=9B=90=EB=9E=98?= =?UTF-8?q?=EB=8C=80=EB=A1=9C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 678e550..e2307a9 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -84,7 +84,7 @@ jobs: env: SHORT_SHA: ${{ needs.ci.outputs.short_sha }} - DEPLOY_BRANCH: test-backend + DEPLOY_BRANCH: dev steps: - name: Clone team2-infra repository