修复中控
This commit is contained in:
+71
-9
@@ -20,7 +20,12 @@ from flask import (
|
||||
)
|
||||
|
||||
from hub_auth import request_allowed
|
||||
from hub_sso import safe_next_path, verify_hub_sso_token
|
||||
from hub_sso import (
|
||||
mint_hub_embed_bootstrap,
|
||||
safe_next_path,
|
||||
verify_hub_embed_bootstrap,
|
||||
verify_hub_sso_token,
|
||||
)
|
||||
|
||||
|
||||
def _hub_auth_required(f):
|
||||
@@ -122,7 +127,7 @@ def install_on_app(
|
||||
|
||||
|
||||
def configure_hub_embed_session(app):
|
||||
"""HTTPS 跨域 iframe 内嵌时须 SameSite=None + Secure,否则 hub-sso 写入的 session 会丢失。"""
|
||||
"""HTTPS iframe 内嵌须 SameSite=None + Secure;hub-sso / hub-embed-auth 自动启用。"""
|
||||
import os
|
||||
|
||||
allowed = (os.getenv("APP_ALLOW_HUB_EMBED") or "true").strip().lower() in (
|
||||
@@ -133,14 +138,45 @@ def configure_hub_embed_session(app):
|
||||
)
|
||||
if not allowed:
|
||||
return
|
||||
secure = (os.getenv("APP_COOKIE_SECURE") or "").strip().lower()
|
||||
if secure not in ("1", "true", "yes", "on"):
|
||||
|
||||
secure_env = (os.getenv("APP_COOKIE_SECURE") or "auto").strip().lower()
|
||||
if secure_env in ("1", "true", "yes", "on"):
|
||||
app.config.update(
|
||||
SESSION_COOKIE_SECURE=True,
|
||||
SESSION_COOKIE_SAMESITE="None",
|
||||
SESSION_COOKIE_HTTPONLY=True,
|
||||
)
|
||||
return
|
||||
app.config.update(
|
||||
SESSION_COOKIE_SECURE=True,
|
||||
SESSION_COOKIE_SAMESITE="None",
|
||||
SESSION_COOKIE_HTTPONLY=True,
|
||||
|
||||
@app.before_request
|
||||
def _hub_embed_session_cookie():
|
||||
if request.path not in ("/hub-sso", "/hub-embed-auth"):
|
||||
return
|
||||
embed = (request.args.get("embed") or "").strip().lower() in (
|
||||
"1",
|
||||
"true",
|
||||
"yes",
|
||||
"on",
|
||||
)
|
||||
in_iframe = (request.headers.get("Sec-Fetch-Dest") or "").lower() == "iframe"
|
||||
if not embed and not in_iframe:
|
||||
return
|
||||
if not request.is_secure:
|
||||
return
|
||||
app.config["SESSION_COOKIE_SECURE"] = True
|
||||
app.config["SESSION_COOKIE_SAMESITE"] = "None"
|
||||
app.config["SESSION_COOKIE_HTTPONLY"] = True
|
||||
|
||||
|
||||
def _sso_wants_embed_auth() -> bool:
|
||||
embed = (request.args.get("embed") or "").strip().lower() in (
|
||||
"1",
|
||||
"true",
|
||||
"yes",
|
||||
"on",
|
||||
)
|
||||
in_iframe = (request.headers.get("Sec-Fetch-Dest") or "").lower() == "iframe"
|
||||
return bool(embed or in_iframe)
|
||||
|
||||
|
||||
def install_hub_embed_headers(app):
|
||||
@@ -310,6 +346,8 @@ def register_hub_routes(app):
|
||||
@app.route("/hub-sso")
|
||||
def hub_sso_login():
|
||||
"""中控签发的临时链接:写入 session 后跳转,直链访问仍走 /login。"""
|
||||
from urllib.parse import urlencode
|
||||
|
||||
auth_disabled = bool(current_app.config.get("HUB_AUTH_DISABLED"))
|
||||
next_arg = request.args.get("next")
|
||||
if auth_disabled:
|
||||
@@ -319,6 +357,11 @@ def register_hub_routes(app):
|
||||
token = (request.args.get("token") or "").strip()
|
||||
ok, next_path, err = verify_hub_sso_token(token, ex)
|
||||
if ok:
|
||||
if _sso_wants_embed_auth() and request.is_secure:
|
||||
boot = mint_hub_embed_bootstrap(ex, next_path)
|
||||
if boot:
|
||||
q = urlencode({"t": boot, "next": next_path, "embed": "1"})
|
||||
return redirect(f"/hub-embed-auth?{q}")
|
||||
session["logged_in"] = True
|
||||
session.modified = True
|
||||
return redirect(next_path)
|
||||
@@ -327,10 +370,29 @@ def register_hub_routes(app):
|
||||
f"中控 SSO 未生效({hint})。"
|
||||
"请确认中控与实例 .env 中 HUB_BRIDGE_TOKEN 一致,"
|
||||
f"且中控设置里该账户 key 为「{ex}」。"
|
||||
"直链实例地址仍需输入 APP_PASSWORD。"
|
||||
"经本地导航 iframe 打开时,实例须 HTTPS 且可设 APP_COOKIE_SECURE=true。"
|
||||
)
|
||||
return redirect("/login")
|
||||
|
||||
@app.route("/hub-embed-auth")
|
||||
def hub_embed_auth_login():
|
||||
"""LocalNav 等 iframe 内嵌:单独写入 SameSite=None 会话后跳转。"""
|
||||
auth_disabled = bool(current_app.config.get("HUB_AUTH_DISABLED"))
|
||||
next_arg = request.args.get("next")
|
||||
if auth_disabled:
|
||||
session["logged_in"] = True
|
||||
return redirect(safe_next_path(next_arg))
|
||||
ex = str((_ctx().get("exchange") or "")).strip().lower()
|
||||
boot = (request.args.get("t") or "").strip()
|
||||
ok, next_path, err = verify_hub_embed_bootstrap(boot, ex)
|
||||
if ok:
|
||||
session["logged_in"] = True
|
||||
session.modified = True
|
||||
return redirect(next_path)
|
||||
hint = err or "校验失败"
|
||||
flash(f"iframe 登录未生效({hint})。可点本地导航工具栏「实例免密」重试。")
|
||||
return redirect("/login")
|
||||
|
||||
|
||||
def _latest_preview_id():
|
||||
get_db = _ctx().get("get_db")
|
||||
|
||||
Reference in New Issue
Block a user