"""允许本地导航(LocalNav)iframe 内嵌本服务。环境变量 NAV_ALLOW_EMBED / NAV_EMBED_ORIGINS。""" from __future__ import annotations import os def nav_embed_allowed() -> bool: return (os.getenv("NAV_ALLOW_EMBED") or "true").strip().lower() in ( "1", "true", "yes", "on", ) def nav_embed_origins() -> str: return (os.getenv("NAV_EMBED_ORIGINS") or "*").strip() or "*" def nav_session_middleware_kwargs() -> dict: """ LocalNav 等跨站 iframe 内登录须 SameSite=None + Secure(仅 HTTPS 站点有效)。 NAV_EMBED_SESSION=1 强制开启;auto 时在配置了 NAV_EMBED_ORIGINS 时开启。 """ raw = (os.getenv("NAV_EMBED_SESSION") or "auto").strip().lower() if raw in ("0", "false", "no", "off"): return {"same_site": "lax", "https_only": False} if raw in ("1", "true", "yes", "on"): return {"same_site": "none", "https_only": True} if raw == "auto": origins = nav_embed_origins() if origins and origins != "*": return {"same_site": "none", "https_only": True} return {"same_site": "lax", "https_only": False} def install_nav_embed(app) -> None: if not nav_embed_allowed(): return origins = nav_embed_origins() @app.middleware("http") async def _nav_embed_frame_headers(request, call_next): response = await call_next(request) if origins == "*": response.headers["Content-Security-Policy"] = "frame-ancestors *" else: parts = " ".join(o.strip() for o in origins.split(",") if o.strip()) response.headers["Content-Security-Policy"] = f"frame-ancestors 'self' {parts}" return response