4.4 KiB
Multi-Domain JWT 토큰 공유 분석
현재 구조 진단
도메인 구성
| 앱 | 도메인 | 포트(로컬) |
|---|---|---|
| cs | cs.onasys.co.kr |
3000 |
| as | as.onasys.co.kr |
3003 |
| backend | 공통 1개 | 8000 |
핵심 문제
브라우저 쿠키는 Same-Origin Policy 적용: cs.onasys.co.kr에서 설정한 쿠키는 as.onasys.co.kr에서 읽을 수 없음.
현재 두 앱 모두 NEXT_PUBLIC_COOKIE_DOMAIN 환경변수가 설정되지 않음 → 쿠키 domain 속성 없음 → 각 앱이 자기 도메인에만 쿠키 저장.
코드 흐름 분석
authConfig.cookieDomain = process.env.NEXT_PUBLIC_COOKIE_DOMAIN (현재 undefined)
↓
token-manager.ts: getCookieDomain() → undefined 반환
↓
setCookie(key, value, { domain: undefined, ... }) ← domain 없이 저장
↓
결과: cs.onasys.co.kr 쿠키 ≠ as.onasys.co.kr 쿠키 (공유 불가)
해결 방법: Parent Domain Cookie
원리
쿠키 Domain 속성을 부모 도메인으로 설정하면 모든 서브도메인이 공유:
Domain=.onasys.co.kr
→ cs.onasys.co.kr ✅ 읽기/쓰기 가능
→ as.onasys.co.kr ✅ 읽기/쓰기 가능
구현 방법
Step 1: 환경변수 추가
apps/cs/.env.production (또는 .env.local 배포용)
NEXT_PUBLIC_COOKIE_DOMAIN=.onasys.co.kr
apps/as/.env.production
NEXT_PUBLIC_COOKIE_DOMAIN=.onasys.co.kr
Important
반드시 앞에
.(점)을 붙여야 서브도메인 전체에 적용됩니다.
Step 2: 코드 변경 불필요
token-manager.ts의 getCookieDomain()이 이미 config.cookieDomain을 사용하고 있으므로, 환경변수만 설정하면 됩니다.
// packages/common/auth/token-manager.ts (현재 코드)
const getCookieDomain = (): string | undefined => {
if (typeof window === "undefined") return undefined;
if (config.cookieDomain) return config.cookieDomain; // ← 이미 준비됨
return undefined;
};
Step 3: 백엔드 CORS 확인
백엔드가 credentials: true와 함께 올바른 Access-Control-Allow-Origin을 반환하는지 확인:
Access-Control-Allow-Origin: https://cs.onasys.co.kr (또는 as.onasys.co.kr)
Access-Control-Allow-Credentials: true
Warning
Access-Control-Allow-Origin: *와credentials: true는 동시에 사용 불가. 명시적 도메인 또는 동적 오리진 허용 필요.
SameSite 주의사항
현재 토큰 매니저 설정:
setCookie(key, value, {
secure: isHttps,
sameSite: "lax", // ← 서브도메인 간 이동 시 쿠키 전송됨 (OK)
domain,
path: "/",
});
sameSite: "lax"→ 서브도메인 간 네비게이션에서 쿠키 전송 가능 ✅sameSite: "strict"→ 다른 도메인에서의 요청에 쿠키 미전송 ❌sameSite: "none"+secure: true→ 크로스사이트 iframe 등에서도 전송 (필요 시)
배포 환경 HTTPS 사용 시 secure: true 자동 적용되므로 문제 없음.
세션 공유 흐름 (적용 후)
사용자가 cs.onasys.co.kr 에서 로그인
↓
setCookie("access-token", jwt, { domain: ".onasys.co.kr" })
↓
브라우저: .onasys.co.kr 쿠키 저장
↓
사용자가 as.onasys.co.kr 으로 이동
↓
브라우저가 자동으로 ".onasys.co.kr" 쿠키 전송
↓
as 앱의 미들웨어: req.cookies.get("access-token") ✅ 정상 읽힘
↓
백엔드 API 호출 시 Authorization 헤더에 토큰 포함
추가 고려사항
로그아웃 처리
한 앱에서 로그아웃 시 도메인 지정 쿠키 삭제 필요:
// removeToken 에서 domain 이 자동 적용됨 (현재 코드 OK)
removeCookie(key, { domain: ".onasys.co.kr", path: "/" });
토큰 갱신 (Refresh Token)
refresh-token 쿠키도 같은 domain 설정 적용 → 두 앱 모두 silent refresh 가능.
로컬 개발 환경
로컬에서는 localhost가 서브도메인을 지원하지 않으므로 별도 처리 불필요 (.env.local에는 설정하지 않음).
최소 변경 요약
| 위치 | 변경 내용 |
|---|---|
apps/cs/.env.production |
NEXT_PUBLIC_COOKIE_DOMAIN=.onasys.co.kr 추가 |
apps/as/.env.production |
NEXT_PUBLIC_COOKIE_DOMAIN=.onasys.co.kr 추가 |
| 소스 코드 | 변경 없음 (이미 cookieDomain 지원 구현됨) |
| 백엔드 | CORS Access-Control-Allow-Origin 명시적 도메인 설정 확인 |