1. 引言与核心分歧
在设计现代微服务、前后端分离系统以及内部运维控制台(如大模型可观测性看板)时,架构师面临的首要安全决策就是前后端之间的身份认证与鉴权流派。
业界目前演进出了两大主流流派:
- 流派一:网关级统一代理与 Cookie 穿透(Gateway Forward-Auth / Token Exchange)
- 流派二:前端持有 Token 与后端无状态验签(Bearer JWT / OIDC PKCE)
很多团队在没有理清业务边界时,盲目跟风引入复杂的前端 OIDC SDK 和 JWT 验签链条,导致前端状态膨胀、跨域配置繁琐;而在需要开放生态 API 时,又受制于 Cookie 限制。
本文将从工程底层原理、适用场景、边界限制,以及如何利用 Cloudflare 边缘反代实现"虚拟同域"等方面,对这两大流派进行全景拆解。
2. 流派一:网关级统一代理模式 (Kong Forward-Auth)
2.1 工作原理与时序拓扑
在网关级代理模式下,前端和业务后端完全不参与复杂的 OAuth 授权码交换与 Token 刷新逻辑,所有的身份拦截、校验和放行全部由集群边缘网关(如 Kong Gateway + OAuth2-Proxy)在最外层终结。
后端 API (/api/v1/logs) 前端 SPA (/dashboard) OAuth2-Proxy & Logto Kong Gateway Cloudflare (Edge CDN) 后端 API (/api/v1/logs) 前端 SPA (/dashboard) OAuth2-Proxy & Logto Kong Gateway Cloudflare (Edge CDN) #mermaid-svg-2mj4NsBprZeHCNPO{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-2mj4NsBprZeHCNPO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-2mj4NsBprZeHCNPO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-2mj4NsBprZeHCNPO .error-icon{fill:#552222;}#mermaid-svg-2mj4NsBprZeHCNPO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2mj4NsBprZeHCNPO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-2mj4NsBprZeHCNPO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2mj4NsBprZeHCNPO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2mj4NsBprZeHCNPO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-2mj4NsBprZeHCNPO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2mj4NsBprZeHCNPO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2mj4NsBprZeHCNPO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2mj4NsBprZeHCNPO .marker.cross{stroke:#333333;}#mermaid-svg-2mj4NsBprZeHCNPO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2mj4NsBprZeHCNPO p{margin:0;}#mermaid-svg-2mj4NsBprZeHCNPO .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-2mj4NsBprZeHCNPO text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-2mj4NsBprZeHCNPO .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-2mj4NsBprZeHCNPO .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-2mj4NsBprZeHCNPO .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-2mj4NsBprZeHCNPO .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-2mj4NsBprZeHCNPO #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-2mj4NsBprZeHCNPO .sequenceNumber{fill:white;}#mermaid-svg-2mj4NsBprZeHCNPO #sequencenumber{fill:#333;}#mermaid-svg-2mj4NsBprZeHCNPO #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-2mj4NsBprZeHCNPO .messageText{fill:#333;stroke:none;}#mermaid-svg-2mj4NsBprZeHCNPO .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-2mj4NsBprZeHCNPO .labelText,#mermaid-svg-2mj4NsBprZeHCNPO .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-2mj4NsBprZeHCNPO .loopText,#mermaid-svg-2mj4NsBprZeHCNPO .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-2mj4NsBprZeHCNPO .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-2mj4NsBprZeHCNPO .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-2mj4NsBprZeHCNPO .noteText,#mermaid-svg-2mj4NsBprZeHCNPO .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-2mj4NsBprZeHCNPO .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-2mj4NsBprZeHCNPO .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-2mj4NsBprZeHCNPO .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-2mj4NsBprZeHCNPO .actorPopupMenu{position:absolute;}#mermaid-svg-2mj4NsBprZeHCNPO .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-2mj4NsBprZeHCNPO .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-2mj4NsBprZeHCNPO .actor-man circle,#mermaid-svg-2mj4NsBprZeHCNPO line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-2mj4NsBprZeHCNPO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} alt未认证 (无 Cookie) 前端调用 API (同域自动带 Cookie) 用户 (浏览器) 访问 https://gw.jppwl.asia/dashboard1转发流量2触发 forward-auth 子请求 (/oauth2/auth)3302 重定向至 Logto 登录授权页4扫码/账号密码授权成功5写入根域 HttpOnly Cookie (Domain=.jppwl.asia)6认证通过,放行加载前端静态资源7GET /api/v1/logs8校验 Cookie 有效性9校验通过,注入 Header: X-Auth-Request-User10转发请求 (携带清洗后的真实身份头)11返回业务数据12 用户 (浏览器)
2.2 核心优势
- 前端代码"零鉴权"侵入 :React / Vue 前端不需要安装任何 OAuth SDK,发请求直接用原生的
fetch('/api/...'),浏览器自动携带同域 Cookie,完全省去了localStorage存 Token、防 XSS 攻击以及定时静默刷新 Token 的繁琐状态机。 - 真正的全站无感单点登录(SSO) :Cookie 作用域设为根域名(如
Domain=.jppwl.asia)。只要用户在系统内的任一服务(如 DbGate、MinIO)登录过,访问看板直接秒开。 - 彻底消除跨域(Zero CORS) :在同域名下通信,不存在任何预检
OPTIONS请求与Access-Control-Allow-Origin配置损耗。 - 边缘绝对防御:未认证的黑客流量在 Kong 网关最外层直接被拦截并重定向,连后端的端口和代码逻辑都碰不到。
3. 流派二:前端持有 JWT 模式 (Bearer Token)
3.1 工作原理与时序拓扑
前端 SPA 单页面应用引入身份提供商(IdP,如 Logto / Auth0)的 SDK,走标准的 OAuth 2.0 PKCE 授权码流程获取 Access Token(JWT),并在随后的每个 API 请求头中携带 Authorization: Bearer <Token>。后端通过公钥(JWKS)对 JWT 签名、有效期及载荷进行本地无状态校验。
业务后端 API 统一认证中心 (Logto Cloud) 前端应用 (@logto/react) 业务后端 API 统一认证中心 (Logto Cloud) 前端应用 (@logto/react) #mermaid-svg-rhvGH6XviczIlerQ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rhvGH6XviczIlerQ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rhvGH6XviczIlerQ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rhvGH6XviczIlerQ .error-icon{fill:#552222;}#mermaid-svg-rhvGH6XviczIlerQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rhvGH6XviczIlerQ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rhvGH6XviczIlerQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rhvGH6XviczIlerQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rhvGH6XviczIlerQ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rhvGH6XviczIlerQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rhvGH6XviczIlerQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rhvGH6XviczIlerQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rhvGH6XviczIlerQ .marker.cross{stroke:#333333;}#mermaid-svg-rhvGH6XviczIlerQ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rhvGH6XviczIlerQ p{margin:0;}#mermaid-svg-rhvGH6XviczIlerQ .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-rhvGH6XviczIlerQ text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-rhvGH6XviczIlerQ .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-rhvGH6XviczIlerQ .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-rhvGH6XviczIlerQ .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-rhvGH6XviczIlerQ .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-rhvGH6XviczIlerQ #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-rhvGH6XviczIlerQ .sequenceNumber{fill:white;}#mermaid-svg-rhvGH6XviczIlerQ #sequencenumber{fill:#333;}#mermaid-svg-rhvGH6XviczIlerQ #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-rhvGH6XviczIlerQ .messageText{fill:#333;stroke:none;}#mermaid-svg-rhvGH6XviczIlerQ .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-rhvGH6XviczIlerQ .labelText,#mermaid-svg-rhvGH6XviczIlerQ .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-rhvGH6XviczIlerQ .loopText,#mermaid-svg-rhvGH6XviczIlerQ .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-rhvGH6XviczIlerQ .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-rhvGH6XviczIlerQ .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-rhvGH6XviczIlerQ .noteText,#mermaid-svg-rhvGH6XviczIlerQ .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-rhvGH6XviczIlerQ .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-rhvGH6XviczIlerQ .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-rhvGH6XviczIlerQ .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-rhvGH6XviczIlerQ .actorPopupMenu{position:absolute;}#mermaid-svg-rhvGH6XviczIlerQ .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-rhvGH6XviczIlerQ .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-rhvGH6XviczIlerQ .actor-man circle,#mermaid-svg-rhvGH6XviczIlerQ line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-rhvGH6XviczIlerQ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 前端将 Token 存入内存/SecureStorage 后端拉取 IdP 公钥 (JWKS) 验签并解析 Payload 用户 (浏览器 / App) 打开应用1发起 OIDC 授权请求 (PKCE 流程)2返回 Access Token (JWT) + Refresh Token3GET /api/v1/logs (Header: Bearer <JWT>)4验签成功,返回数据5 用户 (浏览器 / App)
4. 深度对比:既然流派一体验极佳,为何流派二仍是全球公认标准?
如果网关 Forward-Auth 体验如此丝滑,为什么各大公有云和开放平台依然以流派二为主?因为流派一存在三大物理级限制,而这些正是流派二的用武之地:
4.1 限制一:Cookie 的同根域铁律(跨域无法共享)
- 物理机制 :浏览器安全模型严格限制 Cookie 绝不能跨根域写入或读取 。例如,Cookie 作用在
.jppwl.asia,如果前端托管在https://my-dashboard.vercel.app,浏览器发请求时根本无法把 Cookie 发往不同的域名。 - 流派二的表现 :JWT 只是一个标准的字符串,存在 HTTP Request Header 里,不受任何域名和同源策略的物理限制,跨几百个完全不同的域名都能通用。
4.2 限制二:非浏览器客户端(原生 App、小程序、CLI 脚本)
- 物理机制 :流派一严重依赖浏览器的 302 自动重定向机制与系统的 Cookie Jar 管理器。
- 场景 :如果是 iOS/Android 原生客户端、微信小程序、或者是终端 Python/Go 自动化运维脚本:
- 它们不是完整的浏览器内核,收到网关返回的 302 登录 HTML 时,无法自然弹窗引导登录;
- 移动端系统没有天然的 Cookie 自动管理机制。
- 流派二的表现:原生 App 通过系统 Webview 拿到一次 JWT 后存入钥匙串(Keychain),之后的所有网络请求通过拦截器统一带上 Bearer Header,架构极为标准化。
4.3 限制三:细粒度权限控制与微服务零信任调用(Scopes & Claims)
-
物理机制:流派一通常只能传递"用户是谁(User ID)",网关放行代表"粗粒度信任";
-
流派二的表现 :JWT 本身具备自包含载荷(Self-contained Claims) :
json{ "sub": "user_nvd11", "scopes": ["observability:read", "metrics:export"], "tenant_id": "hsbc_rcdp", "exp": 1788459999 }后端微服务在拿到 Token 后,无需查询数据库或鉴权中心,直接解密即可判断该用户是否拥有特定操作的权限,并且可以在微服务链路(Service-to-Service)中安全透传。
5. 进阶技巧:利用 Cloudflare 边缘反代打破"跨域限制",强行落地流派一
很多时候,前后端物理上部署在不同服务商(例如:前端托管在 Vercel / GitHub Pages,后端部署在自建 K3s 集群)。按照传统认知,这必须使用流派二(处理复杂的 CORS 和 Token)。
但借助 Cloudflare 边缘统一入口(Origin Rules / Worker 反代) ,可以把物理上分离的跨域前后端,在边缘层聚合成"逻辑上的绝对同域",从而无缝享受流派一的零前端代码与无感 SSO 红利!
#mermaid-svg-tT1lVX9tMDDcS0SW{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-tT1lVX9tMDDcS0SW .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-tT1lVX9tMDDcS0SW .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-tT1lVX9tMDDcS0SW .error-icon{fill:#552222;}#mermaid-svg-tT1lVX9tMDDcS0SW .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tT1lVX9tMDDcS0SW .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-tT1lVX9tMDDcS0SW .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tT1lVX9tMDDcS0SW .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tT1lVX9tMDDcS0SW .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-tT1lVX9tMDDcS0SW .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tT1lVX9tMDDcS0SW .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tT1lVX9tMDDcS0SW .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tT1lVX9tMDDcS0SW .marker.cross{stroke:#333333;}#mermaid-svg-tT1lVX9tMDDcS0SW svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tT1lVX9tMDDcS0SW p{margin:0;}#mermaid-svg-tT1lVX9tMDDcS0SW .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-tT1lVX9tMDDcS0SW .cluster-label text{fill:#333;}#mermaid-svg-tT1lVX9tMDDcS0SW .cluster-label span{color:#333;}#mermaid-svg-tT1lVX9tMDDcS0SW .cluster-label span p{background-color:transparent;}#mermaid-svg-tT1lVX9tMDDcS0SW .label text,#mermaid-svg-tT1lVX9tMDDcS0SW span{fill:#333;color:#333;}#mermaid-svg-tT1lVX9tMDDcS0SW .node rect,#mermaid-svg-tT1lVX9tMDDcS0SW .node circle,#mermaid-svg-tT1lVX9tMDDcS0SW .node ellipse,#mermaid-svg-tT1lVX9tMDDcS0SW .node polygon,#mermaid-svg-tT1lVX9tMDDcS0SW .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-tT1lVX9tMDDcS0SW .rough-node .label text,#mermaid-svg-tT1lVX9tMDDcS0SW .node .label text,#mermaid-svg-tT1lVX9tMDDcS0SW .image-shape .label,#mermaid-svg-tT1lVX9tMDDcS0SW .icon-shape .label{text-anchor:middle;}#mermaid-svg-tT1lVX9tMDDcS0SW .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-tT1lVX9tMDDcS0SW .rough-node .label,#mermaid-svg-tT1lVX9tMDDcS0SW .node .label,#mermaid-svg-tT1lVX9tMDDcS0SW .image-shape .label,#mermaid-svg-tT1lVX9tMDDcS0SW .icon-shape .label{text-align:center;}#mermaid-svg-tT1lVX9tMDDcS0SW .node.clickable{cursor:pointer;}#mermaid-svg-tT1lVX9tMDDcS0SW .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-tT1lVX9tMDDcS0SW .arrowheadPath{fill:#333333;}#mermaid-svg-tT1lVX9tMDDcS0SW .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-tT1lVX9tMDDcS0SW .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-tT1lVX9tMDDcS0SW .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tT1lVX9tMDDcS0SW .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-tT1lVX9tMDDcS0SW .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tT1lVX9tMDDcS0SW .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-tT1lVX9tMDDcS0SW .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-tT1lVX9tMDDcS0SW .cluster text{fill:#333;}#mermaid-svg-tT1lVX9tMDDcS0SW .cluster span{color:#333;}#mermaid-svg-tT1lVX9tMDDcS0SW div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-tT1lVX9tMDDcS0SW .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-tT1lVX9tMDDcS0SW rect.text{fill:none;stroke-width:0;}#mermaid-svg-tT1lVX9tMDDcS0SW .icon-shape,#mermaid-svg-tT1lVX9tMDDcS0SW .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tT1lVX9tMDDcS0SW .icon-shape p,#mermaid-svg-tT1lVX9tMDDcS0SW .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-tT1lVX9tMDDcS0SW .icon-shape .label rect,#mermaid-svg-tT1lVX9tMDDcS0SW .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tT1lVX9tMDDcS0SW .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-tT1lVX9tMDDcS0SW .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-tT1lVX9tMDDcS0SW :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 统一入口
路径: / 或 /assets/*
路径: /api/*
浏览器 (统一访问 https://dashboard.jppwl.asia)
Cloudflare Edge 边缘统一调度
前端托管 (Vercel / GitHub Pages)
后端网关与服务 (K3s / OCI)
落地配置示例(Cloudflare Worker 边缘聚合):
javascript
export default {
async fetch(request) {
const url = new URL(request.url);
// 1. 如果是 API 数据接口,无感路由到后端真实集群
if (url.pathname.startsWith("/api/")) {
const backendOrigin = "https://k3s-gateway.jppwl.asia";
const targetUrl = backendOrigin + url.pathname + url.search;
return fetch(targetUrl, request);
}
// 2. 其余静态页面与资源请求,无感路由到前端静态托管
const frontendOrigin = "https://my-dashboard.vercel.app";
const targetUrl = frontendOrigin + url.pathname;
return fetch(targetUrl, request);
}
};
收益:
- 浏览器自始至终认为自己在和
dashboard.jppwl.asia通信; - 完美规避 CORS 跨域限制,Cookie 自动传递;
- 前端保留纯净的静态页面特性,后端完全被 Kong + Logto 统一防护。
6. 选型总结与决策矩阵
| 场景与需求 | 推荐选型 | 核心考量 |
|---|---|---|
| 私有运维看板 / 内部管理系统 (如 LiteLLM 可观测性看板) | 🏆 流派一 (Kong Forward-Auth) | 极简、零前端鉴权代码、全站无感 SSO、大厂内网最佳实践 |
| 公网对外开放开放平台 / 第三方 API 生态 | 🏆 流派二 (Bearer JWT) | 跨域不受限、自包含 Scopes 权限控制 |
| 原生移动端 App / 微信小程序 | 🏆 流派二 (Bearer JWT) | 脱离浏览器 Cookie 机制,标准 OAuth PKCE 流程 |
| 前后端物理分离但属于同一团队 | 🌟 流派一 + Cloudflare 边缘同域 | 利用边缘代理抹平物理域名差异,享受零跨域与 Cookie 免密红利 |
在我们的 LiteLLM Observatory 看板落地中,坚定选用 流派一(Kong 网关统一代理) 作为主交互通道,同时在后端兼容 Master Key 头部验证以支持自动化脚本,达成开发效率与系统安全的最优平衡。