Web 服务模式
桌面端和浏览器用的是同一份 React 界面,区别只在传输层:桌面窗口通过 Tauri IPC 调用 Rust 核心,浏览器则通过 HTTP 与 WebSocket 调用同一批命令。前端启动时检测运行环境自动选择传输方式,因此两边的功能、布局、交互完全一致,你不需要学第二套界面。
Web 服务模式适合这些场景:在手机上临时切换账号;在同一局域网的另一台电脑上查看用量;把配置界面留在一台常开的机器上,其他设备只用浏览器访问。
从桌面端开启
- 打开桌面端的设置。
- 选择 Web 服务 面板。
- 填写主机与端口。默认是
127.0.0.1和3090。 - 确认访问令牌。首次生成配置时会自动填入一个随机 UUID,可以直接用,也可以替换成自己的字符串。
- 点击保存,再点击启动服务。
启动成功后,用浏览器访问 http://127.0.0.1:3090(或你设置的地址)即可。首次打开需要输入访问令牌,令牌保存在浏览器 localStorage 的 ai-switch.webToken 键下,之后同一浏览器不必重复输入。
面板上还有两个可选开关:
- 启动时自动运行:桌面端启动后自动拉起 Web 服务,不必每次手动点。
- 启用安全网络:通过 Tailscale 把服务暴露给你自己的设备或公网,配套的访问模式可选「仅私网」或「公网访问」。这部分详见 远程访问与 HTTPS。
浏览器端的三个入口
| 方法与路径 | 用途 | 鉴权 |
|---|---|---|
POST /api/:command | 所有业务命令的统一入口,命令名放在路径里,参数放在 JSON body | 需要令牌 |
GET /ws/events | WebSocket 事件流,推送账号状态、用量、终端输出等实时事件 | 需要令牌 |
GET /health | 健康检查,用于反向代理或监控探活 | 不需要令牌 |
令牌有两种携带方式:HTTP 请求用 Authorization: Bearer <token> 请求头;WebSocket 因为无法自定义请求头,额外支持 ?token=<token> 查询参数(同时也接受 Bearer 头)。服务端比较令牌时使用常量时间比较,避免时序侧信道。
API 响应统一带上 Cache-Control: no-store,请求体上限为 12 MiB(技能包安装等操作需要较大 body)。CORS 允许任意来源发起 GET/POST/OPTIONS,因此可以从其他前端页面调用,但没有令牌依然拿不到数据。
一个手动调用的例子:
curl -X POST http://127.0.0.1:3090/api/list_accounts \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'curl.exe -X POST http://127.0.0.1:3090/api/list_accounts `
-H "Authorization: Bearer YOUR_TOKEN" `
-H "Content-Type: application/json" `
-d '{}'配置文件
Web 服务的配置持久化在 ~/.ai-switch/web-service.json。界面上的每一项都对应其中一个字段,另外有三个字段目前只能改文件(界面上没有对应控件):
| 字段 | 默认值 | 说明 |
|---|---|---|
host | 127.0.0.1 | 监听地址。非环回地址必须同时配好 TLS,见下一节 |
port | 3090 | 监听端口 |
token | 首次生成时自动写入随机 UUID | 访问令牌 |
autoStart | false | 桌面端启动后自动运行服务 |
tailscaleEnabled | false | 是否启用 Tailscale 暴露 |
tailscaleExposureMode | private | private(仅私网)或 public(Funnel 公网) |
tlsEnabled | false | 是否启用 TLS。界面无此开关,只能改文件 |
tlsCertPath | 空 | 证书链 PEM 路径。界面无此输入框 |
tlsKeyPath | 空 | 私钥 PEM 路径。界面无此输入框 |
修改文件后需要重启 Web 服务才会生效。tlsCertPath 与 tlsKeyPath 必须同时提供,只给一个会以 web.tls_paths_incomplete 报错拒绝启动。
绑定地址与 TLS 的硬性规则
默认监听 127.0.0.1,也就是只有本机能连。想让局域网内其他设备访问,需要显式把 host 改成 0.0.0.0 或某个具体的内网 IP——但这里有一条代码层面的强制规则:
监听非环回地址时,如果没有启用 TLS,服务会直接拒绝启动,返回错误
web.sensitive_transport_requires_tls。
这不是警告而是硬性校验。原因是一部分命令涉及凭据导出、密钥读取、MCP 与技能的安装,明文 HTTP 暴露在网络上风险过高。因此在非环回地址上运行有三条路:
- 用 Tailscale 暴露,保持
host为环回地址(推荐,见 远程访问与 HTTPS)。 - 自备证书,在
web-service.json里填好tlsEnabled/tlsCertPath/tlsKeyPath。 - 保持环回监听,在前面放一个自己负责 TLS 终止的反向代理。
浏览器里不可用的命令
有两类命令在浏览器里拿不到:
桌面独占命令(3 个)依赖原生桌面能力,浏览器调用会返回「仅桌面可用」:打开证书目录、把会话拉到系统终端应用、通过系统保存对话框导出凭据。
敏感命令受一道运行时闸门控制,只有在传输层被判定为安全时才开放。这些命令包括凭据的导出/预览导入/导入、读取代理密钥、从市场安装 MCP、增删改本地 MCP 服务器、以及技能的保存/删除/安装包。闸门关闭时它们返回 404「Web command is not available」,而不是 401——避免通过响应差异探测命令是否存在。
判定为安全的条件是以下任一:
- 走 HTTPS;
- 走 HTTP 且监听环回地址,同时 Tailscale 处于关闭状态;
- 走 HTTP 且监听环回地址,Tailscale 已连接且处于公网(Funnel)模式——此时对外链路由 Tailscale 提供 HTTPS。
另外要注意:访问令牌为空时,敏感命令一律返回 401,普通命令则完全不鉴权。所以令牌虽然在类型上是可选的,实际上是必填项。
终端相关命令(创建会话、写入输入、调整大小、结束会话、列出会话)在 Web API 上是可用的,这意味着拿到令牌的人可以在你的机器上开一个 shell。请把令牌按 SSH 私钥的等级来保护。
安全注意事项
开启前请确认
- 访问令牌必须设置且足够随机。 所有
/api/*与/ws/events请求都需要令牌;令牌为空时敏感命令会被全部拒绝,普通命令则会彻底失去保护。 - 不要随手绑
0.0.0.0。 默认的127.0.0.1只对本机开放。改成非环回地址前先确认这台机器所在网络里有哪些设备,并且已经配好 TLS(否则服务不会启动)。 - 令牌等价于 shell 权限。 Web API 开放了终端会话命令,泄露令牌意味着对方可以在这台机器上执行命令,同时读取所有账号配置。
- 令牌保存在浏览器 localStorage。 在共享或公共设备上访问后请退出并清理站点数据。
- 令牌轮换要手动做。 改完令牌需要重启服务,并且所有浏览器都要重新输入新令牌。
- 公网暴露前请三思。 需要外网访问时优先用 Tailscale 私网,只在确有必要时才启用 Funnel,且两种情况下 AI Switch 自身的令牌校验都不会被跳过。
下一步
- 服务器上没有桌面环境?用 独立服务器 直接跑
ai-switch-server。 - 需要从外网访问或给本地代理配 HTTPS?见 远程访问与 HTTPS。
- 想知道桌面端与 Web 服务共享哪些数据?见 桌面端。
- 想了解命令层在两种传输下如何复用?见 架构总览。