From 482a65958b84546c53bdeaa231b61a0832c587c7 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Thu, 15 Oct 2026 15:01:58 +0800 Subject: [PATCH] =?UTF-8?q?docs(plugins):=20=E8=A1=A5=E3=80=8C=E5=89=8D?= =?UTF-8?q?=E7=BC=80=E4=BB=A3=E7=90=86=E3=80=8D=E7=AB=A0=E8=8A=82=20?= =?UTF-8?q?=E2=80=94=E2=80=94=20=E6=8F=92=E4=BB=B6=E8=87=AA=E8=B5=B7?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E6=8C=82=E5=88=B0=E7=BD=91=E5=85=B3=E5=90=8C?= =?UTF-8?q?=E7=AB=AF=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/plugins.md | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/docs/plugins.md b/docs/plugins.md index deaf260..c238730 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -377,7 +377,48 @@ plugin.http = { 路径,未认证会跳登录页。 - 未声明的路径不会因为落在允许命名空间而被放行——不在 handler 表里就是 404。 -### 5.6 在运行时安装/更新适配器(token 轮换) +### 5.6 前缀代理:把插件自起的服务挂到网关同端口 + +前节的自定义挂载点只能回答**由插件计算出来的内容**(`{status, headers, body/json}`)。 +若插件自己起了一个 TCP/HTTP 服务(典型:服务端浏览器栈 + noVNC),客户端就需要 +**字节级转发**,包括 **WebSocket 升级** —— 前者做不到。 + +为此声明 `prefix = true`,handler 每次请求返回一个**回环目标**: + +```lua +plugin.http = { + { path = "myplugin/proxy/:session", method = "GET", prefix = true, + roles = { "admin" }, handler = "proxy" }, +} + +function plugin.proxy(req) + -- 每次请求都问一遍:会话没了/过期了就返回 404,地址自然失效 + if not sessionAlive(req.params.session) then + return { status = 404, json = { error = "no such session" } } + end + return { proxy = "http://127.0.0.1:60100" } +end +``` + +规则: + +- **只能返回 `{ proxy = <目标> }`**,没有 `status` / `body`。写了 `status` 会被忽略。 +- 目标必须是 **带显式端口的字面回环 IP**(`http://127.0.0.1:60100`)。 + 拒绝 `https://`、`localhost` 这类主机名、无端口、带 userinfo/path/query 的地址。 + 理由:主机名可能被 hosts / DNS / 代理环境改写;通用能力只接受确定性地址。 +- 路由匹配同前缀下的**所有子路径**,`:param` 仍照常捕获,`req.path` 是完整 + 请求路径,子路径由插件自己从 `req.path` 里切。 +- **鉴权先于代理**:`roles` / `keys` / `public` 语义与普通端点一致。 +- **不转发网关凭据**:`Authorization`、`Cookie`、`api_key` 都不会传给后端服务。 +- **拒绝跨站**:`Origin` 与网关自身 host 不一致返回 403。WebSocket 由浏览器 + 发起且自动带 Cookie,否则第三方网页可借管理员会话开隧道。 +- **撤销点唯一**:handler 不再返回目标(或返回 404)即失效,内核不缓存目标。 + +客户端拿到的 URL 是**相对网关口**的绝对路径(如 +`/api/plugins/http/myplugin/proxy//vnc.html`),因此远程访问、HTTPS 入口、 +Cookie 鉴权都自然生效,无需暴露额外端口。 + +### 5.7 在运行时安装/更新适配器(token 轮换) 插件可以在运行时安装、改写**自己的**适配器 —— 这是"带自动轮换的认证"的实现 方式:拿着新 token 重写适配器源码,后续请求自然使用新逻辑(内核重建该适配器