From 0dba231aaca1fa69c2c9ad5d2d335148cce41bf6 Mon Sep 17 00:00:00 2001 From: p_caso Date: Fri, 17 Apr 2026 18:19:23 +0900 Subject: [PATCH 1/5] =?UTF-8?q?fix:=20=EC=86=8C=EC=85=9C=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20OAuth2=20prod=20=ED=99=98=EA=B2=BD=20?= =?UTF-8?q?=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 - Google scope에 openid 추가, Kakao scope에 account_email 추가 - application-prod.yml에 forward-headers-strategy: framework 추가 (리버스 프록시 HTTPS 인식) - application-prod.yml에 cookie.secure: false 추가 (HTTP 환경에서 refresh token 쿠키 정상 전달) - deploy.yml docker run에 SPRING_PROFILES_ACTIVE=prod 및 모든 환경변수 주입 추가 - docker 포트 매핑 8080:8080 → 8081:8080 수정 (소셜 redirect URI 등록 포트 일치) - DB_URL을 DB_HOST, DB_PORT, AUTH_DB_NAME 시크릿으로 조합하도록 수정 Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/deploy.yml | 25 ++++++++++++++++++++++++- src/main/resources/application-prod.yml | 7 +++++++ src/main/resources/application.yml | 2 ++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d1ba61c..62d1e22 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -59,7 +59,30 @@ jobs: docker stop auth-server || true docker rm auth-server || true docker pull bjisu/auth-server:latest - docker run -d --name auth-server -p 8080:8080 bjisu/auth-server:latest + docker run -d --name auth-server -p 8081:8080 \ + -e SPRING_PROFILES_ACTIVE=prod \ + -e APP_BASE_URL=${{ secrets.APP_BASE_URL }} \ + -e JWT_PRIVATE_KEY=${{ secrets.JWT_PRIVATE_KEY }} \ + -e JWT_PUBLIC_KEY=${{ secrets.JWT_PUBLIC_KEY }} \ + -e "DB_URL=jdbc:mysql://${{ secrets.DB_HOST }}:${{ secrets.DB_PORT }}/${{ secrets.AUTH_DB_NAME }}?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true" \ + -e DB_USERNAME=${{ secrets.DB_USERNAME }} \ + -e DB_PASSWORD=${{ secrets.DB_PASSWORD }} \ + -e GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }} \ + -e GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }} \ + -e KAKAO_CLIENT_ID=${{ secrets.KAKAO_CLIENT_ID }} \ + -e KAKAO_CLIENT_SECRET=${{ secrets.KAKAO_CLIENT_SECRET }} \ + -e NAVER_CLIENT_ID=${{ secrets.NAVER_CLIENT_ID }} \ + -e NAVER_CLIENT_SECRET=${{ secrets.NAVER_CLIENT_SECRET }} \ + -e MAIL_USERNAME=${{ secrets.MAIL_USERNAME }} \ + -e MAIL_PASSWORD=${{ secrets.MAIL_PASSWORD }} \ + -e FRONTEND_CALLBACK_URL=${{ secrets.FRONTEND_CALLBACK_URL || 'https://retrip-web.vercel.app/auth/callback' }} \ + -e FRONTEND_PASSWORD_RESET_URL=${{ secrets.FRONTEND_PASSWORD_RESET_URL || 'https://retrip-web.vercel.app/reset-password' }} \ + -e AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }} \ + -e AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }} \ + -e PORTONE_STORE_ID=${{ secrets.PORTONE_STORE_ID }} \ + -e PORTONE_CHANNEL_KEY=${{ secrets.PORTONE_CHANNEL_KEY }} \ + -e PORTONE_API_SECRET=${{ secrets.PORTONE_API_SECRET }} \ + bjisu/auth-server:latest - name: IP 제거 (SSH 포트) if: ${{ always() }} diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 86dcce8..1dd299f 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -1,3 +1,10 @@ +server: + forward-headers-strategy: framework + +app: + cookie: + secure: false + spring: datasource: url: ${DB_URL} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index a86d86d..9c39afb 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -26,6 +26,7 @@ spring: client-id: ${GOOGLE_CLIENT_ID:your-google-client-id} client-secret: ${GOOGLE_CLIENT_SECRET:your-google-client-secret} scope: + - openid - profile - email redirect-uri: "${APP_BASE_URL:http://localhost:8080}/login/oauth2/code/google" @@ -36,6 +37,7 @@ spring: authorization-grant-type: authorization_code scope: - profile_nickname + - account_email redirect-uri: "${APP_BASE_URL:http://localhost:8080}/login/oauth2/code/kakao" client-name: Kakao From 7e02b5091eb4641dd39099bdc005a129ff0a5449 Mon Sep 17 00:00:00 2001 From: p_caso Date: Fri, 17 Apr 2026 18:26:25 +0900 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20test.html=20=EB=B0=8F=20swagger-ui?= =?UTF-8?q?=20=EA=B2=BD=EB=A1=9C=20=EC=9D=B8=EC=A6=9D=20=EC=97=86=EC=9D=B4?= =?UTF-8?q?=20=EC=A0=91=EA=B7=BC=20=ED=97=88=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- .../com/retrip/auth/application/config/SecurityConfig.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/retrip/auth/application/config/SecurityConfig.java b/src/main/java/com/retrip/auth/application/config/SecurityConfig.java index 227e39e..1955157 100644 --- a/src/main/java/com/retrip/auth/application/config/SecurityConfig.java +++ b/src/main/java/com/retrip/auth/application/config/SecurityConfig.java @@ -122,7 +122,8 @@ public SecurityFilterChain securityFilterChain( "/auth/password-reset/by-verification", "/auth/password-reset/by-email", "/auth/password-reset").permitAll() - .requestMatchers("/swagger-ui/**", "/v3/api-docs/**", "/swagger-resources/**", "/webjars/**").permitAll() + .requestMatchers("/swagger-ui/**", "/swagger-ui.html", "/v3/api-docs/**", "/swagger-resources/**", "/webjars/**").permitAll() + .requestMatchers("/test.html", "/").permitAll() // ✅ 추가: 본인인증 및 여행 스타일 조회 API 허용 .requestMatchers(HttpMethod.GET, "/api/travel-styles", "/api/users/check-nickname").permitAll() .requestMatchers(HttpMethod.POST, "/api/auth/verify-identity").authenticated() From 5981fde2bed62b69410f8a8054d2edaeaa85440d Mon Sep 17 00:00:00 2001 From: p_caso Date: Fri, 17 Apr 2026 18:34:31 +0900 Subject: [PATCH 3/5] =?UTF-8?q?fix:=20test.html=EC=9D=84=20static=20?= =?UTF-8?q?=ED=8F=B4=EB=8D=94=EB=A1=9C=20=EC=9D=B4=EB=8F=99=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EB=B0=B0=ED=8F=AC=20=ED=99=98=EA=B2=BD=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=A0=91=EA=B7=BC=20=EA=B0=80=EB=8A=A5=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - test.html이 gitignore에 포함되어 있어 빌드 JAR에 누락, 500 오류 발생 - static 폴더로 이동 시 Spring Boot가 정적 리소스로 서빙 - gitignore에서 test.html 제외 Co-Authored-By: Claude Sonnet 4.6 --- .gitignore | 1 - src/main/resources/{ => static}/test.html | 0 2 files changed, 1 deletion(-) rename src/main/resources/{ => static}/test.html (100%) diff --git a/.gitignore b/.gitignore index 93f67ae..480b112 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,6 @@ application-prod-debug.yml .env.*.local # 테스트 파일 -test.html *.test.html # ==================================== diff --git a/src/main/resources/test.html b/src/main/resources/static/test.html similarity index 100% rename from src/main/resources/test.html rename to src/main/resources/static/test.html From 5b776e377929cf0dcd0e6c2a2472fc384da114ab Mon Sep 17 00:00:00 2001 From: p_caso Date: Fri, 17 Apr 2026 18:45:49 +0900 Subject: [PATCH 4/5] =?UTF-8?q?fix:=20Google=20OAuth2=20scope=EC=97=90?= =?UTF-8?q?=EC=84=9C=20openid=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit openid scope 추가 시 Google이 OIDC 모드로 동작하여 OidcUserService가 사용됨 → CustomOAuth2UserService 호출 안 됨 → authentication.getName()이 UUID가 아닌 Google subject ID 반환 → UUID.fromString() 예외 → /login?error 리다이렉트 profile + email scope만으로 이름/이메일 정상 수신 가능 Co-Authored-By: Claude Sonnet 4.6 --- src/main/resources/application.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9c39afb..c4b0f83 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -26,7 +26,6 @@ spring: client-id: ${GOOGLE_CLIENT_ID:your-google-client-id} client-secret: ${GOOGLE_CLIENT_SECRET:your-google-client-secret} scope: - - openid - profile - email redirect-uri: "${APP_BASE_URL:http://localhost:8080}/login/oauth2/code/google" From 2c68aefac3595cb2d2d8800998a1f23731c84b94 Mon Sep 17 00:00:00 2001 From: p_caso Date: Fri, 17 Apr 2026 18:51:43 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20OAuth2=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=20=EC=8B=A4=ED=8C=A8=20=EC=8B=9C=20/login=3Ferror=20401=20?= =?UTF-8?q?=EB=8C=80=EC=8B=A0=20=ED=94=84=EB=A1=A0=ED=8A=B8=EB=A1=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존에는 OAuth2 실패 시 /login?error로 리다이렉트 되었으나 해당 경로에 핸들러가 없어 401 반환 → 실패 시 프론트 콜백 URL에 ?error= 파라미터로 리다이렉트하도록 수정 Co-Authored-By: Claude Sonnet 4.6 --- .../retrip/auth/application/config/SecurityConfig.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/com/retrip/auth/application/config/SecurityConfig.java b/src/main/java/com/retrip/auth/application/config/SecurityConfig.java index 1955157..8318d47 100644 --- a/src/main/java/com/retrip/auth/application/config/SecurityConfig.java +++ b/src/main/java/com/retrip/auth/application/config/SecurityConfig.java @@ -8,6 +8,7 @@ import com.retrip.auth.infra.adapter.in.rest.filter.LoginAuthenticationFilter; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -33,6 +34,7 @@ import java.util.List; +@Slf4j @Configuration @EnableWebSecurity @RequiredArgsConstructor @@ -68,6 +70,9 @@ public AuthenticationManager authenticationManager( @Value("${app.cookie.secure:true}") private boolean cookieSecure; + @Value("${app.frontend-callback-url:http://localhost:3000/auth/callback}") + private String frontendCallbackUrl; + @Bean public LoginAuthenticationFilter loginAuthenticationFilter( JwtConfig jwtConfig, @@ -111,6 +116,11 @@ public SecurityFilterChain securityFilterChain( .userService(customOAuth2UserService) ) .successHandler(oAuth2LoginSuccessHandler) + .failureHandler((request, response, exception) -> { + log.error("OAuth2 로그인 실패: {}", exception.getMessage()); + response.sendRedirect(frontendCallbackUrl + "?error=" + + java.net.URLEncoder.encode(exception.getMessage(), java.nio.charset.StandardCharsets.UTF_8)); + }) ) .authorizeHttpRequests(auth -> auth