From a8ea265e611a3fe828a75768dc1bbedc2590b32f Mon Sep 17 00:00:00 2001 From: king Date: Sun, 24 May 2026 17:56:09 +0900 Subject: [PATCH] =?UTF-8?q?fix(sso):=20AuthGuard=20=EA=B0=80=20ASGI=20scop?= =?UTF-8?q?e.path=20=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit request.url.path 는 uvicorn --root-path 가 prepend 된 형태(/corm/health/db)라 _AUTH_EXEMPT_PREFIXES 의 /health prefix 와 매칭 안 됐다. scope.path 는 root_path 가 제외된 형태(/health/db)라 정확히 매칭된다. next_path 계산도 같이 정리 (이중 prefix 방지). --- main.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index 73afc73..c9a8c38 100644 --- a/main.py +++ b/main.py @@ -71,7 +71,9 @@ class AuthGuardMiddleware(BaseHTTPMiddleware): """ async def dispatch(self, request: Request, call_next): - path = request.url.path # ASGI 에서 root_path 가 빠진 경로 + # ASGI scope 의 raw path 는 root_path 가 제외된 형태. + # (request.url.path 는 root_path 가 prepend 된 형태라 prefix 매칭이 어긋남) + path = request.scope.get("path", "") for prefix in _AUTH_EXEMPT_PREFIXES: if path == prefix or path.startswith(prefix): return await call_next(request) @@ -85,8 +87,8 @@ class AuthGuardMiddleware(BaseHTTPMiddleware): wants_html = "text/html" in accept or not path.startswith("/api/") if wants_html: next_path = f"{APP_ROOT_PATH}{path}" if APP_ROOT_PATH else path - if request.url.query: - next_path = f"{next_path}?{request.url.query}" + if request.scope.get("query_string"): + next_path = f"{next_path}?{request.scope['query_string'].decode('latin-1')}" sep = "&" if "?" in MAIN_LOGIN_URL else "?" target = f"{MAIN_LOGIN_URL}{sep}next={quote(next_path, safe='/')}" return RedirectResponse(url=target, status_code=302)