fix(sso): comply with dbx-main SSO contract — no session writes, next passthrough, 8h max-age
This commit is contained in:
+1
-1
@@ -24,7 +24,7 @@ SESSION_SECRET_KEY=__paste-same-value-as-dbx-main__
|
|||||||
SESSION_COOKIE_NAME=session
|
SESSION_COOKIE_NAME=session
|
||||||
SESSION_SAME_SITE=lax
|
SESSION_SAME_SITE=lax
|
||||||
SESSION_HTTPS_ONLY=1
|
SESSION_HTTPS_ONLY=1
|
||||||
SESSION_MAX_AGE=1209600
|
SESSION_MAX_AGE=28800
|
||||||
|
|
||||||
# 세션에서 읽을 사용자 식별 키. dbx-main 이 어느 키로 쓰는지에 맞춰라.
|
# 세션에서 읽을 사용자 식별 키. dbx-main 이 어느 키로 쓰는지에 맞춰라.
|
||||||
SESSION_USER_KEY=user_email
|
SESSION_USER_KEY=user_email
|
||||||
|
|||||||
+30
-9
@@ -118,25 +118,46 @@ def get_admin_user(current_user: User = Depends(get_current_user)):
|
|||||||
return current_user
|
return current_user
|
||||||
|
|
||||||
|
|
||||||
def _next_param(request: Request) -> str:
|
def _safe_next(raw: Optional[str]) -> str:
|
||||||
"""로그인 후 돌아올 절대 경로(서브경로 prefix 포함)."""
|
"""클라이언트가 넘긴 next 를 검증. 같은 호스트의 절대경로만 허용.
|
||||||
|
|
||||||
|
dbx-main 측에서도 동일 규칙으로 한 번 더 검증하지만, OMS 단계에서
|
||||||
|
먼저 거른다. 외부 URL / 프로토콜 상대 URL / //, /\\ 등 차단.
|
||||||
|
"""
|
||||||
root = os.getenv("APP_ROOT_PATH", "").rstrip("/")
|
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")
|
@router.get("/login")
|
||||||
async def login(request: Request):
|
async def login(request: Request, next: Optional[str] = None):
|
||||||
"""OMS 자체 로그인 없음. dbx-main 의 로그인 페이지로 위임."""
|
"""OMS 자체 로그인 없음. dbx-main 의 로그인 페이지로 위임.
|
||||||
|
|
||||||
|
클라이언트가 ?next= 로 원래 가려던 경로를 넘기면 그대로 전달한다.
|
||||||
|
없으면 OMS 의 root_path 로 폴백.
|
||||||
|
"""
|
||||||
|
safe = _safe_next(next)
|
||||||
sep = "&" if "?" in MAIN_LOGIN_URL else "?"
|
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)
|
return RedirectResponse(url=target, status_code=302)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/logout")
|
@router.get("/logout")
|
||||||
async def logout(request: Request):
|
async def logout(request: Request):
|
||||||
"""OMS 세션 흔적 제거 후 dbx-main 로그아웃으로 위임."""
|
"""전적으로 dbx-main 에 위임.
|
||||||
request.session.pop(SESSION_USER_KEY, None)
|
|
||||||
request.session.pop(SESSION_NAME_KEY, None)
|
중요: 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)
|
return RedirectResponse(url=MAIN_LOGOUT_URL, status_code=302)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user