中控
This commit is contained in:
+36
-11
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user