Skip to content

[FIX]: 사용자/관리자 토큰 쿠키를 도메인별 분리#219

Merged
marulog merged 2 commits intodevelopfrom
OT-369-feature/seperate-JWT
Mar 23, 2026
Merged

[FIX]: 사용자/관리자 토큰 쿠키를 도메인별 분리#219
marulog merged 2 commits intodevelopfrom
OT-369-feature/seperate-JWT

Conversation

@marulog
Copy link
Copy Markdown
Collaborator

@marulog marulog commented Mar 22, 2026

📝 작업 내용

  • 인증 쿠키를 사용자/관리자 도메인별로 분리 하였습니다. 다만, cdn의 경우 제 파트가 아니라서 관리자<-> 사용자 간 현재 공유되는 형식으로 유지시켰습니다. 추후 리팩토링을 통해 local, dev.yml으로 분리하여 관리하도록 하겠습니다.
  • [ ]

📷 스크린샷

☑️ 체크 리스트

체크 리스트를 확인해주세요

  • 테스트는 잘 통과했나요?
  • 충돌을 해결했나요?
  • 이슈는 등록했나요?
  • 라벨은 등록했나요?

#️⃣ 연관된 이슈

close #218

💬 리뷰 요구사항

현 pr 이후 기존 cookie 유틸 함수에서 주석처리하던게 -> cdn쪽 주석처리하는걸로 변경되었습니다.

Summary by CodeRabbit

릴리스 노트

  • 리팩토링
    • 쿠키 관리 로직이 중앙화되어 도메인 지정이 가능하도록 개선되었습니다.
  • 버그 픽스
    • 로그인/토큰 갱신/로그아웃 흐름에서 레거시 도메인(openthetaste.cloud)에 설정된 액세스·리프레시 쿠키를 명시적으로 삭제하도록 추가되어 세션 정리 신뢰성이 향상되었습니다.
  • 기능 개선
    • CDN 서명 쿠키에도 명시적 도메인 적용이 적용되었습니다.

@marulog marulog self-assigned this Mar 22, 2026
@marulog marulog added the fix 버그 수정 label Mar 22, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 22, 2026

Walkthrough

API 관리·사용 서비스의 CloudFront 서명 쿠키 및 인증 쿠키 처리에 도메인 인자 지원을 추가했습니다. 공통 CookieUtil에 도메인 인자를 받는 오버로드가 추가되었고, 여러 핸들러/컨트롤러는 레거시 도메인(openthetaste.cloud)에 대해 기존 쿠키를 삭제한 뒤 새 쿠키를 설정하도록 변경되었습니다.

Changes

Cohort / File(s) Summary
CloudFront 쿠키 도메인 설정
apps/api-admin/src/main/java/com/ott/api_admin/auth/cdn/CloudFrontSignedCookieService.java, apps/api-user/src/main/java/com/ott/api_user/auth/cdn/CloudFrontSignedCookieService.java
CloudFront 서명 쿠키(CloudFront-Policy, CloudFront-Signature, CloudFront-Key-Pair-Id) 추가/삭제 호출에 하드코딩된 도메인 "openthetaste.cloud" 인자를 전달하도록 변경(기존 호출은 주석 처리).
인증 컨트롤러 — 레거시 도메인 정리
apps/api-admin/src/main/java/com/ott/api_admin/auth/controller/AdminAuthController.java, apps/api-user/src/main/java/com/ott/api_user/auth/controller/AuthController.java, apps/api-user/src/main/java/com/ott/api_user/auth/oauth2/handler/OAuth2SuccessHandler.java
login/reissue/logout/OAuth2 성공 흐름에서 레거시 도메인(openthetaste.cloud)에 설정된 accessToken/refreshToken 쿠키를 명시적으로 삭제하도록 추가(일부에 TODO 주석으로 제거 예정일 표기).
공통 유틸리티 — 도메인 인자 지원 추가
modules/common-security/src/main/java/com/ott/common/security/util/CookieUtil.java
새 오버로드 addCookie(..., String domain)deleteCookie(..., String domain) 추가. 기존 메서드는 domain=null로 위임하고, 도메인이 주어질 때만 domain 속성을 설정하도록 리팩터링. 불필요한 import 추가 및 파일 끝 newline 누락 포함.

Sequence Diagram(s)

mermaid
sequenceDiagram
autonumber
participant Client
participant AuthController
participant CookieUtil
participant CloudFrontService
Note over AuthController,CookieUtil: 인증 흐름(예: reissue/login/logout)
Client->>AuthController: 요청(reissue/login/logout)
AuthController->>CookieUtil: deleteCookie(name="accessToken", domain="openthetaste.cloud")
AuthController->>CookieUtil: deleteCookie(name="refreshToken", domain="openthetaste.cloud")
AuthController->>CookieUtil: addCookie(name="accessToken", value, maxAge)
AuthController->>CookieUtil: addCookie(name="refreshToken", value, maxAge)
AuthController->>CloudFrontService: addSignedCookies(response)
CloudFrontService->>CookieUtil: addCookie("CloudFront-Policy", ..., domain="openthetaste.cloud")
CloudFrontService->>CookieUtil: addCookie("CloudFront-Signature", ..., domain="openthetaste.cloud")
CloudFrontService->>CookieUtil: addCookie("CloudFront-Key-Pair-Id", ..., domain="openthetaste.cloud")
CookieUtil-->>AuthController: 응답(쿠키 설정 완료)
AuthController-->>Client: HTTP 응답(쿠키 포함)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • phonil
  • arlen02-01
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 주요 변경사항인 사용자/관리자 토큰 쿠키의 도메인별 분리를 명확하게 요약하고 있습니다.
Linked Issues check ✅ Passed PR의 모든 코드 변경사항이 이슈 #218의 요구사항인 도메인별 쿠키 분리를 충족하고 있습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 도메인별 쿠키 분리라는 이슈 범위 내에 있으며, 범위를 벗어난 변경은 없습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch OT-369-feature/seperate-JWT

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can suggest fixes for GitHub Check annotations.

Configure the reviews.tools.github-checks setting to adjust the time to wait for GitHub Checks to complete.

@marulog marulog requested a review from yubin012 March 22, 2026 16:59
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/api-admin/src/main/java/com/ott/api_admin/auth/cdn/CloudFrontSignedCookieService.java (1)

71-77: P2: CloudFront 쿠키 도메인은 코드 주석 토글 대신 설정으로 분리하는 편이 안전합니다.

근거: apps/api-admin/src/main/java/com/ott/api_admin/auth/cdn/CloudFrontSignedCookieService.java Line 71-77, Line 86-92에서 환경 고정 도메인 리터럴을 하드코딩하고 local용 호출을 주석으로 남겨 두었습니다. 이 방식은 local/dev/prod 전환 때 소스 수정이 필요해 잘못된 도메인이 커밋되기 쉽고, apps/api-user/src/main/java/com/ott/api_user/auth/cdn/CloudFrontSignedCookieService.java Line 71-92에도 같은 패턴이 반복됩니다. cloudfront.signed-cookie.cookie-domain 같은 설정을 주입하고, 값이 비어 있으면 기본 오버로드를 사용하도록 바꾸면 환경별 분기를 코드 변경 없이 처리할 수 있습니다.

♻️ 리팩터링 예시
+    `@Value`("${cloudfront.signed-cookie.cookie-domain:}")
+    private String cookieDomain;
+
     public void addSignedCookies(HttpServletResponse response) {
         ...
-        cookieUtil.addCookie(response, POLICY_COOKIE, cloudFrontBase64(policy.getBytes(StandardCharsets.UTF_8)), ttlMillis, "openthetaste.cloud");
-        cookieUtil.addCookie(response, SIGNATURE_COOKIE, cloudFrontBase64(signatureBytes), ttlMillis, "openthetaste.cloud");
-        cookieUtil.addCookie(response, KEY_PAIR_ID_COOKIE, keyPairId, ttlMillis, "openthetaste.cloud");
+        if (cookieDomain == null || cookieDomain.isBlank()) {
+            cookieUtil.addCookie(response, POLICY_COOKIE, cloudFrontBase64(policy.getBytes(StandardCharsets.UTF_8)), ttlMillis);
+            cookieUtil.addCookie(response, SIGNATURE_COOKIE, cloudFrontBase64(signatureBytes), ttlMillis);
+            cookieUtil.addCookie(response, KEY_PAIR_ID_COOKIE, keyPairId, ttlMillis);
+        } else {
+            cookieUtil.addCookie(response, POLICY_COOKIE, cloudFrontBase64(policy.getBytes(StandardCharsets.UTF_8)), ttlMillis, cookieDomain);
+            cookieUtil.addCookie(response, SIGNATURE_COOKIE, cloudFrontBase64(signatureBytes), ttlMillis, cookieDomain);
+            cookieUtil.addCookie(response, KEY_PAIR_ID_COOKIE, keyPairId, ttlMillis, cookieDomain);
+        }
     }
// clearSignedCookies(...)도 같은 기준으로 분기

Also applies to: 86-92

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/api-admin/src/main/java/com/ott/api_admin/auth/cdn/CloudFrontSignedCookieService.java`
around lines 71 - 77, Replace the hardcoded domain and commented local calls in
CloudFrontSignedCookieService by injecting a configurable property (e.g.
cloudfront.signed-cookie.cookie-domain) into the service and use it when calling
cookieUtil.addCookie(POLICY_COOKIE, SIGNATURE_COOKIE, KEY_PAIR_ID_COOKIE); if
the injected value is null/empty, fall back to the existing overloads that don't
specify a domain so behavior remains unchanged for local tests; apply the exact
same change to clearSignedCookies(...) and mirror the refactor in the
corresponding CloudFrontSignedCookieService in the api-user module so both
services read the shared configuration instead of using literal
"openthetaste.cloud" or commented calls.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@modules/common-security/src/main/java/com/ott/common/security/util/CookieUtil.java`:
- Around line 18-25: The migration missed expiring legacy shared-domain cookies
alongside the new host-only cookies; update places that call addCookie/addCookie
overloads (e.g., usages in OAuth2SuccessHandler and AuthController) so that
before issuing new accessToken/refreshToken you call deleteCookie(response,
"accessToken", "openthetaste.cloud") and deleteCookie(response, "refreshToken",
"openthetaste.cloud"), then call addCookie(response, ...) as normal, and
likewise update logout paths to call both deleteCookie(response, "accessToken",
"openthetaste.cloud") and deleteCookie(response, "refreshToken",
"openthetaste.cloud") in addition to the existing deleteCookie(response,
"accessToken") and deleteCookie(response, "refreshToken"); use the existing
CookieUtil methods (addCookie, deleteCookie, buildCookie) so both legacy domain
and new host-only cookies are expired during roll-out.

---

Nitpick comments:
In
`@apps/api-admin/src/main/java/com/ott/api_admin/auth/cdn/CloudFrontSignedCookieService.java`:
- Around line 71-77: Replace the hardcoded domain and commented local calls in
CloudFrontSignedCookieService by injecting a configurable property (e.g.
cloudfront.signed-cookie.cookie-domain) into the service and use it when calling
cookieUtil.addCookie(POLICY_COOKIE, SIGNATURE_COOKIE, KEY_PAIR_ID_COOKIE); if
the injected value is null/empty, fall back to the existing overloads that don't
specify a domain so behavior remains unchanged for local tests; apply the exact
same change to clearSignedCookies(...) and mirror the refactor in the
corresponding CloudFrontSignedCookieService in the api-user module so both
services read the shared configuration instead of using literal
"openthetaste.cloud" or commented calls.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 37f221a7-de8a-4c04-b588-a8a1102bfd38

📥 Commits

Reviewing files that changed from the base of the PR and between 763526a and 123dfc7.

📒 Files selected for processing (3)
  • apps/api-admin/src/main/java/com/ott/api_admin/auth/cdn/CloudFrontSignedCookieService.java
  • apps/api-user/src/main/java/com/ott/api_user/auth/cdn/CloudFrontSignedCookieService.java
  • modules/common-security/src/main/java/com/ott/common/security/util/CookieUtil.java

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/api-admin/src/main/java/com/ott/api_admin/auth/controller/AdminAuthController.java (1)

49-51: 레거시 쿠키 삭제 로직을 상수/헬퍼로 묶어 중복을 줄이는 것을 권장합니다.

현재처럼 하드코딩이 3곳에 반복되면, 마이그레이션 종료 시점 정리나 도메인 변경 시 누락 가능성이 커집니다.

리팩터링 예시
 public class AdminAuthController implements AdminAuthApi {
+    private static final String LEGACY_SHARED_COOKIE_DOMAIN = "openthetaste.cloud";
+    private static final String ACCESS_TOKEN_COOKIE = "accessToken";
+    private static final String REFRESH_TOKEN_COOKIE = "refreshToken";
+
+    private void deleteLegacySharedDomainAuthCookies(HttpServletResponse response) {
+        cookie.deleteCookie(response, ACCESS_TOKEN_COOKIE, LEGACY_SHARED_COOKIE_DOMAIN);
+        cookie.deleteCookie(response, REFRESH_TOKEN_COOKIE, LEGACY_SHARED_COOKIE_DOMAIN);
+    }

@@
-        cookie.deleteCookie(response, "accessToken", "openthetaste.cloud");
-        cookie.deleteCookie(response, "refreshToken", "openthetaste.cloud");
+        deleteLegacySharedDomainAuthCookies(response);

@@
-        cookie.deleteCookie(response, "accessToken", "openthetaste.cloud");
-        cookie.deleteCookie(response, "refreshToken", "openthetaste.cloud");
+        deleteLegacySharedDomainAuthCookies(response);

@@
-        cookie.deleteCookie(response, "accessToken", "openthetaste.cloud");
-        cookie.deleteCookie(response, "refreshToken", "openthetaste.cloud");
+        deleteLegacySharedDomainAuthCookies(response);

Also applies to: 75-77, 95-97

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/api-admin/src/main/java/com/ott/api_admin/auth/controller/AdminAuthController.java`
around lines 49 - 51, The three duplicated legacy-cookie delete calls in
AdminAuthController (the cookie.deleteCookie(response, "accessToken",
"openthetaste.cloud") and cookie.deleteCookie(response, "refreshToken",
"openthetaste.cloud") occurrences at lines around 49-51, 75-77, 95-97) should be
consolidated: introduce a constant for the legacy domain and constants (or an
enum) for legacy cookie names, and add a small helper method (e.g.,
deleteLegacyCookies(HttpServletResponse response) or
CookieUtils.deleteLegacyCookies(response)) that performs both deletes; then
replace the repeated inline calls with a single call to that helper to reduce
duplication and centralize future changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@apps/api-admin/src/main/java/com/ott/api_admin/auth/controller/AdminAuthController.java`:
- Around line 49-51: The three duplicated legacy-cookie delete calls in
AdminAuthController (the cookie.deleteCookie(response, "accessToken",
"openthetaste.cloud") and cookie.deleteCookie(response, "refreshToken",
"openthetaste.cloud") occurrences at lines around 49-51, 75-77, 95-97) should be
consolidated: introduce a constant for the legacy domain and constants (or an
enum) for legacy cookie names, and add a small helper method (e.g.,
deleteLegacyCookies(HttpServletResponse response) or
CookieUtils.deleteLegacyCookies(response)) that performs both deletes; then
replace the repeated inline calls with a single call to that helper to reduce
duplication and centralize future changes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1214052d-bdb4-450f-8333-77b9e0b51568

📥 Commits

Reviewing files that changed from the base of the PR and between 123dfc7 and fdce52a.

📒 Files selected for processing (3)
  • apps/api-admin/src/main/java/com/ott/api_admin/auth/controller/AdminAuthController.java
  • apps/api-user/src/main/java/com/ott/api_user/auth/controller/AuthController.java
  • apps/api-user/src/main/java/com/ott/api_user/auth/oauth2/handler/OAuth2SuccessHandler.java

Copy link
Copy Markdown
Contributor

@yubin012 yubin012 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다 ~

@marulog marulog merged commit b9cc48c into develop Mar 23, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix 버그 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[OT-369] [FEAT]: 도메인별 토큰 분리

2 participants