diff --git a/.env.example b/.env.example index bf0917a..6716d3d 100644 --- a/.env.example +++ b/.env.example @@ -24,7 +24,7 @@ SESSION_SECRET_KEY=__paste-same-value-as-dbx-main__ SESSION_COOKIE_NAME=session SESSION_SAME_SITE=lax SESSION_HTTPS_ONLY=1 -SESSION_MAX_AGE=1209600 +SESSION_MAX_AGE=28800 # 세션에서 읽을 사용자 식별 키. dbx-main 이 어느 키로 쓰는지에 맞춰라. SESSION_USER_KEY=user_email diff --git a/app/auth.py b/app/auth.py index d14af78..17b1c10 100644 --- a/app/auth.py +++ b/app/auth.py @@ -118,25 +118,46 @@ def get_admin_user(current_user: User = Depends(get_current_user)): return current_user -def _next_param(request: Request) -> str: - """로그인 후 돌아올 절대 경로(서브경로 prefix 포함).""" +def _safe_next(raw: Optional[str]) -> str: + """클라이언트가 넘긴 next 를 검증. 같은 호스트의 절대경로만 허용. + + dbx-main 측에서도 동일 규칙으로 한 번 더 검증하지만, OMS 단계에서 + 먼저 거른다. 외부 URL / 프로토콜 상대 URL / //, /\\ 등 차단. + """ root = os.getenv("APP_ROOT_PATH", "").rstrip("/") - return f"{root}/" if root else "/" + fallback = f"{root}/" if root else "/" + if not raw: + return fallback + candidate = raw.strip() + if not candidate.startswith("/"): + return fallback + if candidate.startswith("//") or candidate.startswith("/\\"): + return fallback + return candidate @router.get("/login") -async def login(request: Request): - """OMS 자체 로그인 없음. dbx-main 의 로그인 페이지로 위임.""" +async def login(request: Request, next: Optional[str] = None): + """OMS 자체 로그인 없음. dbx-main 의 로그인 페이지로 위임. + + 클라이언트가 ?next= 로 원래 가려던 경로를 넘기면 그대로 전달한다. + 없으면 OMS 의 root_path 로 폴백. + """ + safe = _safe_next(next) sep = "&" if "?" in MAIN_LOGIN_URL else "?" - target = f"{MAIN_LOGIN_URL}{sep}next={_next_param(request)}" + target = f"{MAIN_LOGIN_URL}{sep}next={safe}" return RedirectResponse(url=target, status_code=302) @router.get("/logout") async def logout(request: Request): - """OMS 세션 흔적 제거 후 dbx-main 로그아웃으로 위임.""" - request.session.pop(SESSION_USER_KEY, None) - request.session.pop(SESSION_NAME_KEY, None) + """전적으로 dbx-main 에 위임. + + 중요: OMS 는 절대로 request.session 을 modify 하지 않는다. + NPM 이 proxy_cookie_path / /orderlist/; 로 Set-Cookie 의 path 를 + 재작성하므로, OMS 가 세션 쿠키를 쓰면 dbx-main 의 path=/ 쿠키와 + 분리된 path=/orderlist/ 쿠키가 만들어져 SSO 가 깨진다. + """ return RedirectResponse(url=MAIN_LOGOUT_URL, status_code=302)