From e73b22bf74a7c873afb3cf46351fed2ff71b071c Mon Sep 17 00:00:00 2001 From: Suyeon Lee <112858914+choubung@users.noreply.github.com> Date: Mon, 17 Nov 2025 18:14:05 +0900 Subject: [PATCH 1/8] =?UTF-8?q?chore:=20=ED=8F=AC=ED=8A=B8=20=EC=A7=80?= =?UTF-8?q?=EC=A0=95=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.properties | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 83f2591..3a46631 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,6 +1,5 @@ spring.application.name=openMission spring.profiles.include=oauth -server.port=${PORT:9090} spring.datasource.url=${DB_URL:jdbc:h2:./mydb;AUTO_SERVER=TRUE} spring.datasource.username=${DB_USERNAME:sa} @@ -11,4 +10,4 @@ spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true # H2 -spring.h2.console.enabled=false \ No newline at end of file +spring.h2.console.enabled=false From 9e978deb4716d24bfbc55313e8fe4f56071b0db0 Mon Sep 17 00:00:00 2001 From: Suyeon Lee <112858914+choubung@users.noreply.github.com> Date: Mon, 17 Nov 2025 18:19:32 +0900 Subject: [PATCH 2/8] Update application.properties --- src/main/resources/application.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3a46631..4dea8c8 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,6 @@ spring.application.name=openMission spring.profiles.include=oauth +server.port=8080 spring.datasource.url=${DB_URL:jdbc:h2:./mydb;AUTO_SERVER=TRUE} spring.datasource.username=${DB_USERNAME:sa} From 07ac8553527b54d8cdf456c31405eef8f631a259 Mon Sep 17 00:00:00 2001 From: Suyeon Lee <112858914+choubung@users.noreply.github.com> Date: Mon, 17 Nov 2025 18:24:45 +0900 Subject: [PATCH 3/8] =?UTF-8?q?chore:=20dockerfile=20=ED=8F=AC=ED=8A=B8=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index a8b9c38..f52d639 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,6 @@ ARG JAR_FILE=build/libs/*.jar COPY ${JAR_FILE} app.jar -EXPOSE 9090 +EXPOSE 8080 -ENTRYPOINT ["java", "-jar", "/app.jar"] \ No newline at end of file +ENTRYPOINT ["java", "-jar", "/app.jar"] From 2fb3eeabd112c0b82ed7cc8580860d05eebbb43c Mon Sep 17 00:00:00 2001 From: Suyeon Lee <112858914+choubung@users.noreply.github.com> Date: Mon, 17 Nov 2025 18:25:32 +0900 Subject: [PATCH 4/8] =?UTF-8?q?chore:=20application.propertise=20=ED=8F=AC?= =?UTF-8?q?=ED=8A=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4dea8c8..eb71436 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,6 +1,6 @@ spring.application.name=openMission spring.profiles.include=oauth -server.port=8080 +server.port=${PORT:9090} spring.datasource.url=${DB_URL:jdbc:h2:./mydb;AUTO_SERVER=TRUE} spring.datasource.username=${DB_USERNAME:sa} From 367344464db888fa80cbf8483d2870eaa69b4469 Mon Sep 17 00:00:00 2001 From: Suyeon Lee <112858914+choubung@users.noreply.github.com> Date: Mon, 17 Nov 2025 18:57:26 +0900 Subject: [PATCH 5/8] =?UTF-8?q?chore:=20cd=20=EA=B3=A0=EA=B8=89=20?= =?UTF-8?q?=EC=98=B5=EC=85=98=20flags=EB=A1=9C=20=EC=98=AE=EA=B8=B0?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cd.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index e083d61..915c248 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -64,10 +64,9 @@ jobs: # Docker Hub에 푸시한 이미지를 지정 image: '${{ secrets.GCP_REGION }}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/memo-app-repo/backend-deep-dive:${{ env.IMAGE_TAG }}' - # 9. [핵심] Cloud Run과 GCP SQL을 '내부 터널'로 연결 - add-cloudsql-instances: ${{ secrets.GCP_SQL_CONNECTION_NAME }} - - min_instances: 1 + flags: | + --min-instances=1 + --add-cloudsql-instances=${{ secrets.GCP_SQL_CONNECTION_NAME }} # Cloud Run 컨테이너에 환경 변수 주입 env_vars: | From dd53f067ccb0e632e75306b9ad3e90af8a67114f Mon Sep 17 00:00:00 2001 From: choubung Date: Mon, 17 Nov 2025 23:56:16 +0900 Subject: [PATCH 6/8] =?UTF-8?q?fix:=20csrf=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/auth/SecurityConfig.java | 3 ++ .../openMission/web/GlobalModelAdvice.java | 20 +++++++++++++ src/main/resources/static/js/app/index.js | 30 +++++++++++++++++-- .../templates/layout/header.mustache | 10 +++---- 4 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/precourse/openMission/web/GlobalModelAdvice.java diff --git a/src/main/java/com/precourse/openMission/config/auth/SecurityConfig.java b/src/main/java/com/precourse/openMission/config/auth/SecurityConfig.java index daee272..f2f3a30 100644 --- a/src/main/java/com/precourse/openMission/config/auth/SecurityConfig.java +++ b/src/main/java/com/precourse/openMission/config/auth/SecurityConfig.java @@ -21,6 +21,9 @@ public class SecurityConfig { @Bean protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http + .requiresChannel(channel -> channel + .anyRequest().requiresSecure() + ) .authorizeHttpRequests((authz) -> authz .requestMatchers("/").permitAll() diff --git a/src/main/java/com/precourse/openMission/web/GlobalModelAdvice.java b/src/main/java/com/precourse/openMission/web/GlobalModelAdvice.java new file mode 100644 index 0000000..e4f8486 --- /dev/null +++ b/src/main/java/com/precourse/openMission/web/GlobalModelAdvice.java @@ -0,0 +1,20 @@ +package com.precourse.openMission.web; + +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.security.web.csrf.CsrfToken; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.stereotype.Controller; + +/** + * 모든 컨트롤러(@Controller)의 Model에 + * 공통 속성(Attribute)을 추가하는 클래스 + */ +@ControllerAdvice(annotations = Controller.class) +public class GlobalModelAdvice { + @ModelAttribute("_csrf") + public CsrfToken csrfToken(HttpServletRequest request) { + // Spring Security가 이미 request에 저장해 둔 _csrf 토큰을 꺼내서 Model에 담아줌 + return (CsrfToken) request.getAttribute(CsrfToken.class.getName()); + } +} diff --git a/src/main/resources/static/js/app/index.js b/src/main/resources/static/js/app/index.js index bff5e10..5d23787 100644 --- a/src/main/resources/static/js/app/index.js +++ b/src/main/resources/static/js/app/index.js @@ -12,6 +12,11 @@ var main = { $('#btn-delete').on('click', function () { _this.delete(); }); + + $('#btn-logout').on('click', function (e) { + e.preventDefault(); // 태그의 링크 이동을 막음 + _this.logout(); + }); }, save : function () { // 1. [수정] DTO에 맞게 데이터 수집 @@ -71,7 +76,7 @@ var main = { dataType: 'json', contentType:'application/json; charset=utf-8', data: JSON.stringify(data), - beforeSend : function(xhr) { // 💡 (여기도) + beforeSend : function(xhr) { xhr.setRequestHeader(header, token); } }).done(function() { @@ -100,8 +105,29 @@ var main = { }).fail(function (error) { alert(error.responseJSON.message || JSON.stringify(error)); }); - } + }, + logout : function () { + // 9. 태그에서 CSRF 파라미터 이름과 토큰 값을 읽어옴 + var token = $("meta[name='_csrf']").attr("content"); + var paramName = $("meta[name='_csrf_parameter']").attr("content"); + + // 10. 동적으로
을 생성 + var $form = $('
'); + $form.attr('action', '/logout'); + $form.attr('method', 'POST'); + + // 11. 폼에 CSRF 토큰(hidden input)을 추가 + $form.append($('', { + type: 'hidden', + name: paramName, + value: token + })); + + // 12. 폼을 body에 추가하고 즉시 submit + $form.appendTo('body'); + $form.submit(); + } }; main.init(); \ No newline at end of file diff --git a/src/main/resources/templates/layout/header.mustache b/src/main/resources/templates/layout/header.mustache index df57c57..3f7827a 100644 --- a/src/main/resources/templates/layout/header.mustache +++ b/src/main/resources/templates/layout/header.mustache @@ -2,7 +2,10 @@ 메모 서비스 - + + + + @@ -20,10 +23,7 @@