03 查看者强制只读代理 本节摘要:这是第 4 章最硬核的一节。viewer 的「只读」怎么保证?不是靠前端隐藏写按钮(前端可被绕过),而是在服务端代理引擎请求的层强制把关——viewer 的非 GET/HEAD 请求直接拒绝。本节讲清这套「反代层强制只读」,并论证为什么「靠前端隐藏」永远不够。 一、为什么 viewer 只读是真问题 先看为什么这件事需要特别强调。viewer 是「只读」scope,但「只读」这个约束怎么落实? 朴素想法:前端隐藏写按钮,viewer 用户看不到,就改不了。 问题:前端可以被绕过。 考虑攻击场景: 所以「靠前端隐藏」是不够的——只要服务端不强制,任何人拿 viewer 令牌都能绕过前端直接调写接口。真正的只读必须在服务端强制。
本节摘要:这是第 4 章最硬核的一节。viewer 的「只读」怎么保证?不是靠前端隐藏写按钮(前端可被绕过),而是在服务端代理引擎请求的层强制把关——viewer 的非 GET/HEAD 请求直接拒绝。本节讲清这套「反代层强制只读」,并论证为什么「靠前端隐藏」永远不够。
先看为什么这件事需要特别强调。viewer 是「只读」scope,但「只读」这个约束怎么落实?
考虑攻击场景:
恶意用户拿到 viewer 令牌 │ ▼ 不走前端(前端隐藏了写按钮) │ ▼ 直接用工具(如 curl)调服务端的写接口 │ ▼ 如果服务端不检查 ──► 写操作成功!viewer 「只读」被绕过
所以「靠前端隐藏」是不够的——只要服务端不强制,任何人拿 viewer 令牌都能绕过前端直接调写接口。真正的只读必须在服务端强制。
OpenWork 在哪一层强制 viewer 只读?在服务端代理引擎请求的层(第 3 章 03 节)。逻辑很简单:
服务端收到请求(带 viewer 令牌) │ ▼ 即将代理给引擎 │ ▼ 检查:scope == viewer 且 方法 != GET/HEAD? │ ├─ 是 ──► 拒绝(403, viewer 只读) │ └─ 否 ──► 继续代理
也就是说,viewer 令牌的任何写操作(POST/PUT/DELETE 等,以及非 GET/HEAD 的方法),在「即将转发给引擎」时被服务端硬性拒绝。
这个检查在反代层,意味着:
你可能会问:为什么不每个业务 handler 自己检查 scope?要在反代层统一检查?两个理由:
反代层是「所有引擎请求的必经之路」。在这里检查,保证没有漏网之鱼——不管哪个 handler、哪个路径,只要方法非 GET/HEAD 且 viewer,一律拒绝。如果在每个 handler 自己检查,容易漏(某个 handler 忘了写检查)。
反代层在「转发给引擎之前」检查,如果拒绝,请求根本不会到引擎——省了引擎那边的开销。如果在业务层(handler 里)检查,请求已经过了一些处理才被拒,浪费。
用例子感受这套强制:
viewer 用户想删一个文件(写操作) │ ▼ 用 curl 直接调服务端写接口(绕过前端) DELETE /workspace/abc/session/.../file Authorization: Bearer owt_xxx(viewer) │ ▼ 服务端收到,即将代理给引擎 │ ▼ 反代层检查:scope=viewer 且方法=DELETE(非 GET/HEAD) │ ▼ 拒绝!403 Forbidden「viewer 只读」 │ ◄─ viewer 用户:操作被拒
不管 viewer 用户怎么绕前端,服务端反代层都会拦下来。这才是「真只读」。
这是本节要传递的核心认知,值得反复强调。「靠前端隐藏」的安全措施为什么永远不够:
| 问题 | 后果 |
|---|---|
| 前端可被绕过(用 curl/工具直调 API) | 隐藏的写操作能被直接调用 |
| 前端代码可被改(浏览器开发者工具) | 隐藏的按钮能被显示出来 |
| 前端逻辑可被改 | 限制条件能被去掉 |
前端是「用户体验」层,不是「安全」层。前端隐藏按钮是为了「不让用户误点」,不是「防恶意」。真正的安全必须在服务端——因为服务端是攻击者够不到的地方。
⚠️ 黄金法则:任何安全约束,都必须在服务端(或更下层)强制,前端只是「锦上添花」。OpenWork 的 viewer 只读在反代层强制,正是这条法则的体现。
这里有个细节值得提:虽然 viewer 被强制只读,但 collaborator 必须能回复权限询问(因为 collaborator 能写,写操作可能触发 Agent 的权限询问,collaborator 要能回复)。
所以在反代层的检查里,对「权限回复」这种特殊路径,collaborator 是放行的(它需要回复询问才能继续干活)。这是「只读强制」与「权限询问协作」之间的细微平衡——viewer 全禁,collaborator 在权限询问这条特殊路径放行。
只读强制讲清了,最后一节讲审批模式与令牌服务。