From cfff5990b23b526b88096a10fba0e2f074583368 Mon Sep 17 00:00:00 2001 From: ThreeeJ <2171266@hansung.ac.kr> Date: Mon, 11 May 2026 23:38:55 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20Referer=20=EA=B8=B0=EB=B0=98=20OAuth?= =?UTF-8?q?2=20=ED=94=84=EB=A1=A0=ED=8A=B8=20=EB=A6=AC=EB=8B=A4=EC=9D=B4?= =?UTF-8?q?=EB=A0=89=ED=8A=B8=20URI=20=EC=9E=90=EB=8F=99=20=EB=B6=84?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...eOAuth2AuthorizationRequestRepository.java | 8 ++++++++ .../oauth/OAuth2LoginSuccessHandler.java | 19 +++++++++++++++++-- src/main/resources/application.properties | 3 ++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/hansung/zigma/global/oauth/CookieOAuth2AuthorizationRequestRepository.java b/src/main/java/org/hansung/zigma/global/oauth/CookieOAuth2AuthorizationRequestRepository.java index 8a3b25c..6537a31 100644 --- a/src/main/java/org/hansung/zigma/global/oauth/CookieOAuth2AuthorizationRequestRepository.java +++ b/src/main/java/org/hansung/zigma/global/oauth/CookieOAuth2AuthorizationRequestRepository.java @@ -12,6 +12,7 @@ public class CookieOAuth2AuthorizationRequestRepository implements AuthorizationRequestRepository { private static final String COOKIE_NAME = "oauth2_auth_request"; + public static final String REDIRECT_TARGET_COOKIE = "redirect_target"; private static final int COOKIE_EXPIRE_SECONDS = 180; // 3분 // 쿠키에서 Authorization Request 조회 @@ -30,10 +31,16 @@ public void saveAuthorizationRequest( HttpServletResponse response) { if (authorizationRequest == null) { CookieUtils.deleteCookie(request, response, COOKIE_NAME); + CookieUtils.deleteCookie(request, response, REDIRECT_TARGET_COOKIE); return; } CookieUtils.addCookie(response, COOKIE_NAME, CookieUtils.serialize(authorizationRequest), COOKIE_EXPIRE_SECONDS); + + // Referer 헤더로 출발지(local/deploy) 판단 후 쿠키 저장 + String referer = request.getHeader("Referer"); + String target = (referer != null && referer.contains("localhost")) ? "local" : "deploy"; + CookieUtils.addCookie(response, REDIRECT_TARGET_COOKIE, target, COOKIE_EXPIRE_SECONDS); } // 쿠키에서 Authorization Request 꺼내고 삭제 @@ -43,6 +50,7 @@ public OAuth2AuthorizationRequest removeAuthorizationRequest( HttpServletResponse response) { OAuth2AuthorizationRequest authorizationRequest = loadAuthorizationRequest(request); CookieUtils.deleteCookie(request, response, COOKIE_NAME); + // REDIRECT_TARGET_COOKIE는 SuccessHandler에서 사용 후 삭제 return authorizationRequest; } } diff --git a/src/main/java/org/hansung/zigma/global/oauth/OAuth2LoginSuccessHandler.java b/src/main/java/org/hansung/zigma/global/oauth/OAuth2LoginSuccessHandler.java index 940a230..79582c9 100644 --- a/src/main/java/org/hansung/zigma/global/oauth/OAuth2LoginSuccessHandler.java +++ b/src/main/java/org/hansung/zigma/global/oauth/OAuth2LoginSuccessHandler.java @@ -1,10 +1,12 @@ package org.hansung.zigma.global.oauth; +import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.hansung.zigma.global.jwt.CustomUserDetails; import org.hansung.zigma.global.jwt.JwtTokenProvider; +import org.hansung.zigma.global.util.CookieUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; @@ -20,8 +22,11 @@ public class OAuth2LoginSuccessHandler extends SimpleUrlAuthenticationSuccessHan private final JwtTokenProvider jwtTokenProvider; - @Value("${app.oauth2.front-redirect-uri}") - private String redirectUri; + @Value("${app.oauth2.front-redirect-uri.local}") + private String localRedirectUri; + + @Value("${app.oauth2.front-redirect-uri.deploy}") + private String deployRedirectUri; @Override public void onAuthenticationSuccess( @@ -34,6 +39,16 @@ public void onAuthenticationSuccess( userDetails.getUser().getId().toString() ); + // 출발지(local/deploy) 쿠키 보고 리다이렉트 URI 선택, 누락 시 deploy 폴백 + String target = CookieUtils.getCookie(request, + CookieOAuth2AuthorizationRequestRepository.REDIRECT_TARGET_COOKIE) + .map(Cookie::getValue) + .orElse("deploy"); + String redirectUri = "local".equals(target) ? localRedirectUri : deployRedirectUri; + + CookieUtils.deleteCookie(request, response, + CookieOAuth2AuthorizationRequestRepository.REDIRECT_TARGET_COOKIE); + String targetUrl = UriComponentsBuilder.fromUriString(redirectUri) .queryParam("accessToken", accessToken) .build().toUriString(); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e50f234..a6946ea 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -20,7 +20,8 @@ jwt.access.expiration = ${JWT_ACCESS_EXPIRATION} jwt.refresh.expiration = ${JWT_REFRESH_EXPIRATION} # Frontend -app.oauth2.front-redirect-uri=https://z-igma.vercel.app//oauth/callback +app.oauth2.front-redirect-uri.local=http://localhost:5173/oauth/callback +app.oauth2.front-redirect-uri.deploy=https://z-igma.vercel.app/oauth/callback # Web Push web-push.vapid-public-key=${WEB_PUSH_VAPID_PUBLIC_KEY:} From ee51120e9fc6923d52395be8d6ccc44987c5980a Mon Sep 17 00:00:00 2001 From: ThreeeJ <2171266@hansung.ac.kr> Date: Mon, 11 May 2026 23:51:58 +0900 Subject: [PATCH 2/2] =?UTF-8?q?refactor=20:=20=ED=99=98=EA=B2=BD=20?= =?UTF-8?q?=EC=8B=9D=EB=B3=84=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EC=83=81?= =?UTF-8?q?=EC=88=98=ED=99=94=20=EB=B0=8F=20Referer=20startsWith=20?= =?UTF-8?q?=EA=B2=80=EC=82=AC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oauth/CookieOAuth2AuthorizationRequestRepository.java | 7 ++++++- .../zigma/global/oauth/OAuth2LoginSuccessHandler.java | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/hansung/zigma/global/oauth/CookieOAuth2AuthorizationRequestRepository.java b/src/main/java/org/hansung/zigma/global/oauth/CookieOAuth2AuthorizationRequestRepository.java index 6537a31..0d54cd9 100644 --- a/src/main/java/org/hansung/zigma/global/oauth/CookieOAuth2AuthorizationRequestRepository.java +++ b/src/main/java/org/hansung/zigma/global/oauth/CookieOAuth2AuthorizationRequestRepository.java @@ -13,6 +13,8 @@ public class CookieOAuth2AuthorizationRequestRepository private static final String COOKIE_NAME = "oauth2_auth_request"; public static final String REDIRECT_TARGET_COOKIE = "redirect_target"; + public static final String TARGET_LOCAL = "local"; + public static final String TARGET_DEPLOY = "deploy"; private static final int COOKIE_EXPIRE_SECONDS = 180; // 3분 // 쿠키에서 Authorization Request 조회 @@ -38,8 +40,11 @@ public void saveAuthorizationRequest( CookieUtils.serialize(authorizationRequest), COOKIE_EXPIRE_SECONDS); // Referer 헤더로 출발지(local/deploy) 판단 후 쿠키 저장 + // contains 대신 startsWith로 호스트 부분만 검사 (http://attacker.com/localhost 같은 케이스 차단) String referer = request.getHeader("Referer"); - String target = (referer != null && referer.contains("localhost")) ? "local" : "deploy"; + boolean isLocal = referer != null + && (referer.startsWith("http://localhost") || referer.startsWith("https://localhost")); + String target = isLocal ? TARGET_LOCAL : TARGET_DEPLOY; CookieUtils.addCookie(response, REDIRECT_TARGET_COOKIE, target, COOKIE_EXPIRE_SECONDS); } diff --git a/src/main/java/org/hansung/zigma/global/oauth/OAuth2LoginSuccessHandler.java b/src/main/java/org/hansung/zigma/global/oauth/OAuth2LoginSuccessHandler.java index 79582c9..6880d66 100644 --- a/src/main/java/org/hansung/zigma/global/oauth/OAuth2LoginSuccessHandler.java +++ b/src/main/java/org/hansung/zigma/global/oauth/OAuth2LoginSuccessHandler.java @@ -43,8 +43,9 @@ public void onAuthenticationSuccess( String target = CookieUtils.getCookie(request, CookieOAuth2AuthorizationRequestRepository.REDIRECT_TARGET_COOKIE) .map(Cookie::getValue) - .orElse("deploy"); - String redirectUri = "local".equals(target) ? localRedirectUri : deployRedirectUri; + .orElse(CookieOAuth2AuthorizationRequestRepository.TARGET_DEPLOY); + String redirectUri = CookieOAuth2AuthorizationRequestRepository.TARGET_LOCAL.equals(target) + ? localRedirectUri : deployRedirectUri; CookieUtils.deleteCookie(request, response, CookieOAuth2AuthorizationRequestRepository.REDIRECT_TARGET_COOKIE);