From 4f89cdd97eaed700cd67c45f3b45f4294e354b96 Mon Sep 17 00:00:00 2001 From: meraki6512 Date: Thu, 11 Sep 2025 19:03:17 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[#133]=20chore:=20CI/CD=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20SecurityConfig=20C?= =?UTF-8?q?ORS=20=EC=84=A4=EC=A0=95=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - deploy: 실행 프로세스 중지 후 재실행 로직 추가 - ci-docker: PR 보낼 때도 실행하도록 변경 - SecurityConfig: cors.allowed-origins 설정 --- .github/workflows/ci-docker.yml | 2 + .github/workflows/deploy.yml | 11 +++- .../com/issueDive/config/SecurityConfig.java | 27 ++-------- .../resources/application.properties.example | 53 +++++++++++++++++++ 4 files changed, 68 insertions(+), 25 deletions(-) create mode 100644 src/main/resources/application.properties.example diff --git a/.github/workflows/ci-docker.yml b/.github/workflows/ci-docker.yml index 72c0235..21b66e8 100644 --- a/.github/workflows/ci-docker.yml +++ b/.github/workflows/ci-docker.yml @@ -3,6 +3,8 @@ name: IssueDive Docker CI on: push: branches: [ "dev" ] # dev 브랜치에 푸시될 때 실행 + pull_request: + branches: [ "dev" ] # PR 보낼 때도 실행 jobs: build-and-push: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 83aa4d0..a1fb71a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -28,8 +28,15 @@ jobs: docker pull ${{ secrets.DOCKERHUB_USERNAME }}/issuedive:latest # 3. 기존에 실행 중인 앱 컨테이너가 있다면 중지하고 삭제 (최초 실행 시 오류가 나지 않도록 || true 추가) - docker stop issuedive-app || true - docker rm issuedive-app || true + # docker stop issuedive-app || true + # docker rm issuedive-app || true + # -> 8080 포트를 사용하는 기존 컨테이너를 찾아 중지 및 삭제 로직으로 변경 + # 컨테이너 이름과 상관없이 포트 기준으로 찾기 때문에 더 안정적 + CONTAINER_ID=$(docker ps -q --filter "publish=8080") + if [ -n "$CONTAINER_ID" ]; then + docker stop $CONTAINER_ID + docker rm $CONTAINER_ID + fi # 4. 최신 이미지로 새로운 앱 컨테이너 실행 # 이전에 생성한 Docker 네트워크와 .env 파일을 사용합니다. diff --git a/src/main/java/com/issueDive/config/SecurityConfig.java b/src/main/java/com/issueDive/config/SecurityConfig.java index 7b6bb64..dc98f4d 100644 --- a/src/main/java/com/issueDive/config/SecurityConfig.java +++ b/src/main/java/com/issueDive/config/SecurityConfig.java @@ -1,6 +1,7 @@ package com.issueDive.config; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; @@ -8,14 +9,9 @@ import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; 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.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.web.cors.CorsConfiguration; @@ -32,12 +28,12 @@ @RequiredArgsConstructor public class SecurityConfig { - private final CustomUserDetailsService userDetailsService; // DB 기반 인증 private final JwtAuthenticationFilter jwtAuthenticationFilter; // JWT 필터 + @Value("${cors.allowed-origins}") + private String allowedOrigins; // 공개적으로 접근 가능한 URL 목록 - // private static final String[] PUBLIC_URLS = { "/swagger-ui/**", "/v3/api-docs/**", @@ -69,11 +65,9 @@ public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); // 프론트엔드 서버 주소 허용 - configuration.setAllowedOrigins(Arrays.asList("http://localhost:5173", "http://localhost:5174")); + configuration.setAllowedOrigins(Arrays.asList(allowedOrigins.split(","))); // 모든 HTTP 메서드 허용 configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")); - // 모든 헤더 허용 -// configuration.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept", "Authorization")); configuration.addAllowedHeader("*"); // 자격 증명(쿠키 등) 허용 configuration.setAllowCredentials(true); @@ -88,19 +82,6 @@ public CorsConfigurationSource corsConfigurationSource() { public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } - - /* - @Bean - public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) { - UserDetails user = User.withUsername("test") - .password(passwordEncoder.encode("test")) - .roles("USER") - .build(); - return new InMemoryUserDetailsManager(user); - } - - */ - @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { return config.getAuthenticationManager(); diff --git a/src/main/resources/application.properties.example b/src/main/resources/application.properties.example new file mode 100644 index 0000000..42fe688 --- /dev/null +++ b/src/main/resources/application.properties.example @@ -0,0 +1,53 @@ +# =================================================================== +# Example Configuration +# ------------------------------------------------------------------- +# ? ??? ???? 'application.properties' ??? ??? ?, +# ??? ?? ??? ?? ?? <...> ??? ?????. +# 'application.properties' ??? .gitignore? ??? ????? ???. +# =================================================================== + +# --- Database (MySQL) Settings --- +# ?????? ??? ?? URL, ??? ??, ????? ?????. +spring.datasource.url=jdbc:mysql://localhost:3306/issue_dive?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true +spring.datasource.username= +spring.datasource.password= +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + +# --- JPA & Hibernate Settings --- +spring.jpa.hibernate.ddl-auto=none +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=true +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect +# spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect + +# --- Hikari Connection Pool Settings --- +spring.datasource.hikari.connection-test-query=SELECT 1 +spring.datasource.hikari.maximum-pool-size=10 + +# --- Flyway Migration Settings --- +spring.flyway.enabled=true +spring.flyway.locations=classpath:db/migration +spring.flyway.baseline-on-migrate=true + +# --- CORS Settings for Local Development --- +# ?? ?? ? ??? ????? ?????. +cors.allowed-origins=http://localhost:5173, http://localhost:5174 + +# --- Application Logging Settings --- +logging.level.root=INFO +logging.level.org.hibernate.SQL=DEBUG +logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE +logging.level.org.springframework.web=DEBUG +logging.level.com.example.issueDive=DEBUG +logging.file.name=logs/issueDive.log +logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n + +# --- Application Settings --- +spring.application.name=issueDive + +# --- Jackson --- +# spring.jackson.date-format=yyyy-MM-dd HH:mm:ss +# spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false + +# --- K6 performance test Profile --- +#spring.profiles.active=performance \ No newline at end of file From ed7f65ac3ee92d5160887b60ec91219701d54630 Mon Sep 17 00:00:00 2001 From: meraki6512 Date: Thu, 11 Sep 2025 19:16:53 +0900 Subject: [PATCH 2/2] =?UTF-8?q?[#133]=20chore:=20application-test.properti?= =?UTF-8?q?es=20CORS=20=ED=99=98=EA=B2=BD=20=EB=B3=80=EC=88=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/resources/application-test.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/resources/application-test.properties b/src/test/resources/application-test.properties index 5f3f23c..9549e82 100644 --- a/src/test/resources/application-test.properties +++ b/src/test/resources/application-test.properties @@ -1,3 +1,5 @@ +cors.allowed-origins=http://localhost:5173, http://localhost:5174 + # ================================================================= # H2 ??????? MySQL ?? ??? ???? ?? DB? ???? ????? ?? # ? ?? ??? V1__init.sql? AUTO_INCREMENT ??? ?? ?? ?????.