This commit is contained in:
dekun
2026-05-30 11:57:00 +08:00
parent 4c4af4a464
commit 8ffe46a344
6 changed files with 165 additions and 14 deletions
+36 -11
View File
@@ -34,8 +34,11 @@ from hub_web_auth import (
SESSION_MAX_AGE_SEC,
cookie_secure_for_request,
create_session_token,
embed_allowed,
embed_frame_ancestors,
is_public_path,
password_required,
set_session_cookie,
validate_session_token,
expected_username,
verify_credentials,
@@ -141,6 +144,18 @@ async def local_only(request: Request, call_next):
return await call_next(request)
@app.middleware("http")
async def embed_frame_headers(request: Request, call_next):
response = await call_next(request)
if embed_allowed():
ancestors = embed_frame_ancestors()
if ancestors == "*":
response.headers["Content-Security-Policy"] = "frame-ancestors *"
else:
response.headers["Content-Security-Policy"] = f"frame-ancestors 'self' {ancestors}"
return response
@app.middleware("http")
async def hub_password_gate(request: Request, call_next):
if not password_required():
@@ -196,17 +211,27 @@ def api_auth_login(body: LoginBody, request: Request):
if not verify_credentials(body.username, body.password):
raise HTTPException(status_code=401, detail="用户名或密码错误")
token = create_session_token(body.username)
secure = cookie_secure_for_request(request)
resp = JSONResponse({"ok": True})
resp.set_cookie(
SESSION_COOKIE,
token,
httponly=True,
samesite="lax",
path="/",
max_age=SESSION_MAX_AGE_SEC,
secure=secure,
)
resp = JSONResponse({"ok": True, "session_token": token})
set_session_cookie(resp, request, token)
return resp
@app.get("/embed-auth")
def embed_auth_login(request: Request, token: str = "", next: str = "/monitor"):
"""
嵌入式打开:父页跨域 fetch 登录时 Cookie 可能写不进 iframe
用 session_token 在本页做一次导航,在 iframe 内写入 hub_sess。
"""
from fastapi.responses import RedirectResponse
dest = safe_next_path(next)
if not password_required():
return RedirectResponse(dest, status_code=302)
if not validate_session_token(token):
q = urlencode({"next": dest, "embed": "1"})
return RedirectResponse(f"/login?{q}", status_code=302)
resp = RedirectResponse(dest, status_code=302)
set_session_cookie(resp, request, token)
return resp