Open WebUI在frp内网穿透下的访问路径重写问题:子路径子域名与Cookie处理

文章导读
Open WebUI 通过 frp 内网穿透对公网提供服务时,遇到静态资源 404、登录后立刻失效或 Cookie 作用域串到其他应用,通常不是 frp 转发本身的问题,而是应用感知的外部路径与浏览器实际访问路径不一致。frp 只做网络转发,不重写应用内部的资源路径和 Cookie 作用域,所以需要在应用或前端反代层处理。
📋 目录
  1. 先分清两种暴露方式,再动手改配置
  2. 子域名方案:frp 配置最省事
  3. 子路径方案:需要同时处理代理重写和 Cookie
  4. Cookie 处理要点
  5. 验证清单
A A

Open WebUI 通过 frp 内网穿透对公网提供服务时,遇到静态资源 404、登录后立刻失效或 Cookie 作用域串到其他应用,通常不是 frp 转发本身的问题,而是应用感知的外部路径与浏览器实际访问路径不一致。frp 只做网络转发,不重写应用内部的资源路径和 Cookie 作用域,所以需要在应用或前端反代层处理。

建议优先使用独立子域名暴露 Open WebUI;若必须使用子路径,需要确认应用支持 base path 配置,并同时改写请求转发、静态资源引用和 Set-Cookie 的 Path。frp 配置本身不负责路径重写,Cookie 的 Secure/SameSite 需要与访问协议保持一致。

先分清两种暴露方式,再动手改配置

在 frp 服务端允许 HTTP 隧道时,访问方式有两种:一种是把 Open WebUI 挂在独立子域名,例如 openwebui.example.com;另一种是在已有域名下加子路径,例如 example.com/openwebui。两者的处理难度差别很大。子域名方式前端不需要改路径,应用仍然以根路径访问,只要 Cookie 作用域限定在当前子域即可;子路径方式则要求应用生成的页面、接口和 Cookie 都以 /openwebui/ 为根,这会牵涉很多内部逻辑。

子域名方案:frp 配置最省事

配置 frp 的 HTTP 隧道后,让 Open WebUI 直接通过子域名访问。frp 服务端需开启 vhost_http_port,然后定义一个 HTTP 代理,指向内网 Open WebUI 地址。下面是一段可参考的客户端配置:

[openwebui]
type = http
local_ip = 192.168.1.100
local_port = 8080
custom_domains = openwebui.example.com

如果 frp 服务端已经配置了泛解析,也可以改用 subdomain = openwebui,访问地址变成 openwebui.example.com。这种方式下,Open WebUI 本身不知道 frp 的存在,生成的页面链接都指向当前域名根路径,静态资源加载通常正常。需要注意,如果 Open WebUI 有“公开访问地址”或外部 URL 设置,应将其设置为实际访问地址,避免邮件或分享链接指向内网地址。

子路径方案:需要同时处理代理重写和 Cookie

如果必须用子路径,比较稳妥的做法是在 frp 之前或之后再加一个 nginx 反代。以下配置把公网 /openwebui/ 映射到内网 Open WebUI 的根路径:

Open WebUI在frp内网穿透下的访问路径重写问题:子路径子域名与Cookie处理
location /openwebui/ {
    proxy_pass http://127.0.0.1:8080/;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Prefix /openwebui/;
    proxy_cookie_path / /openwebui/;

    # 需要时加上 websocket 升级
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
}

这个片段里,proxy_pass 末尾的 / 会把请求 URI 中的 /openwebui/ 前缀去掉,再转发给后端。proxy_cookie_path 会把后端返回的 Path=/ 改为 Path=/openwebui/,保证 Cookie 只在子路径下发送。这里隐藏的风险是:如果 Open WebUI 内部引用了以 / 开头的静态资源,浏览器会直接请求 /_next/static/... 而不是 /openwebui/_next/static/...,导致资源 404。如果后台设置中无法给应用配置 base path,子路径方案很难完整跑通。

Cookie 处理要点

无论哪种方式,最终都需要检查浏览器里的 Cookie 属性。子域名方式下,Cookie 的 Domain 一般继承当前域名,不会跨到其他子域;但如果 frp 暴露的是 HTTP,而你在浏览器里访问的是 HTTPS,Cookie 的 Secure 标记会被浏览器拒绝,登录状态会反复丢失。这时需要在 TLS 终结层正确传递 X-Forwarded-Proto,或把 Cookie 设置为 Secure 且域名匹配。

子路径方式下,除了 Path 要重写,还要注意 SameSite 属性。如果 Open WebUI 和前端反代在同一站点,SameSite=Lax 通常足够;如果嵌入到跨站 iframe 中,则需要设置 SameSite=None 并配合 Secure,但在 frp 场景下不建议让登录 Cookie 跨站暴露。

验证清单

  1. 用 curl 检查资源是否可达:例如访问 https://openwebui.example.comhttps://example.com/openwebui/,看返回的状态码和 Location。
  2. 打开浏览器开发者工具,刷新页面后看 Network 面板,确认是否有静态资源请求指向了根路径。若出现 /_next/static/ 404,说明应用没有感知子路径。
  3. 检查 Application 面板中的 Cookie。子路径方式下,Cookie 的 Path 应该包含 /openwebui;子域名方式下,Domain 应该只覆盖当前子域。
  4. 登录后刷新页面,确认会话没有丢失。如果丢失,优先看协议是 HTTP 还是 HTTPS,以及 Secure 属性是否匹配。

实际处理时,优先选子域名,其次再考虑子路径。子路径不是不能做,但要求应用支持 base path,并且静态资源全部走相对路径或统一加前缀。若 Open WebUI 当前版本不支持,建议先在子域名下跑通,再逐步验证 Cookie 行为,避免把时间花在不可控的资源 404 追踪上。