From 1f8d2e64e7721d4071e582fd3898a6da6ee97446 Mon Sep 17 00:00:00 2001 From: dekun Date: Sat, 30 May 2026 15:40:43 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gate_order_executor/app/main.py | 12 ++++++++++++ nav_embed.py | 34 +++++++++++++++++++++++++++++++++ onchain_scout_gate/app/web.py | 12 ++++++++++++ 部署说明.md | 34 +++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+) create mode 100644 nav_embed.py diff --git a/gate_order_executor/app/main.py b/gate_order_executor/app/main.py index ecbd5fb..e152681 100644 --- a/gate_order_executor/app/main.py +++ b/gate_order_executor/app/main.py @@ -149,6 +149,18 @@ async def _lifespan(_app: FastAPI): app = FastAPI(title="Gate Order Executor", version="0.2.0", lifespan=_lifespan) +try: + import sys + from pathlib import Path as _Path + + _root = _Path(__file__).resolve().parent.parent.parent + if str(_root) not in sys.path: + sys.path.insert(0, str(_root)) + from nav_embed import install_nav_embed + + install_nav_embed(app) +except Exception: + pass app.add_middleware( SessionMiddleware, secret_key=settings.app.session_secret, diff --git a/nav_embed.py b/nav_embed.py new file mode 100644 index 0000000..461ee9b --- /dev/null +++ b/nav_embed.py @@ -0,0 +1,34 @@ +"""允许本地导航(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 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 diff --git a/onchain_scout_gate/app/web.py b/onchain_scout_gate/app/web.py index 48a0e3c..c627a44 100644 --- a/onchain_scout_gate/app/web.py +++ b/onchain_scout_gate/app/web.py @@ -179,6 +179,18 @@ def create_app(settings: Settings) -> FastAPI: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="unauthorized") app = FastAPI(title="MATRIX FUNNEL", version="2.1.0") + try: + import sys + from pathlib import Path as _Path + + _root = _Path(__file__).resolve().parent.parent.parent + if str(_root) not in sys.path: + sys.path.insert(0, str(_root)) + from nav_embed import install_nav_embed + + install_nav_embed(app) + except Exception: + pass app.add_middleware(GZipMiddleware, minimum_size=800) app.add_middleware( SessionMiddleware, diff --git a/部署说明.md b/部署说明.md index 74640fc..d299c3c 100644 --- a/部署说明.md +++ b/部署说明.md @@ -423,6 +423,40 @@ pm2 save --- +## 13. 接入本地导航(LocalNav) + +**扫描端 / 执行器一般在本仓库所在云服务器**;办公室或家里的 [LocalNav](https://git.bz121.com/dekun/LocalNav) 通过 HTTPS 链接触发 iframe 内嵌(不是把 gate_scout 装在本机)。 + +| 服务 | 云主机端口 | 面板路径 | +|------|------------|----------| +| 扫描端 | 8088 | `/dashboard` | +| 执行器 | 8090 | `/dashboard` | + +**云上(PM2 / systemd 环境变量)** — 允许本地导航页嵌入: + +```env +NAV_ALLOW_EMBED=true +NAV_EMBED_ORIGINS=http://192.168.8.6:5070 +``` + +**本机 LocalNav `.env`** — 指向云地址(子域名反代示例): + +```env +NAV_SEED_GATE_SCOUT=1 +NAV_GATE_SCOUT_UPDATE=1 +NAV_GATE_SCOUT_SCHEME=https +NAV_GATE_SCOUT_SCOUT_HOST=scout.example.com +NAV_GATE_EXECUTOR_HOST=exec.example.com +NAV_GATE_SCOUT_PORT=443 +NAV_GATE_EXECUTOR_PORT=443 +``` + +重启 LocalNav 后左侧出现 **「Gate 扫单」**。若之前误配成 `127.0.0.1`,设 `NAV_GATE_SCOUT_UPDATE=1` 再重启即可覆盖。 + +公网须 **Nginx HTTPS 反代** + `auth.enabled: true`;**不要**对公网裸奔 8088/8090。 + +--- + ## 相关文档 | 文档 | 路径 |