文章目录
低代码平台的数据页面,默认是长在登录体系里的:组织内的人打开页面,自动带着登录态查数据。但有一类需求偏偏要给"不在组织里的人"用——我们厂区的门岗保安不在公司钉钉组织内,却要查"某员工是否被批准携带手机进入生产区域"。权限的唯一依据是 OA 审批单,数据在低代码平台里,而保安没有账号。
这篇文章记录这个"匿名访问"需求的完整攻坚过程:三重墙、两次方案迭代、最终架构,以及两个差点造成静默故障的运维坑。
一、需求与约束
- 数据源:OA 审批单(员工提交"生产区域手机使用授权"申请,审批通过后有使用期限与适用区域);
- 使用者:门岗保安,无企业账号,用门口的电脑或手机打开一个网址;
- 失败语义:查询失败绝不能显示为"无权限"——fail-closed:加载失败必须明确提示"数据加载失败",宁可让人多跑一趟问 HR,也不能把有权限的人误拦在门外(或反过来误放行)。
二、三重墙
第一重:数据接口的登录墙
平台自定义页面的取数接口(表单查询、连接器调用)都是同源接口 + 登录态校验。组织内用户无感,匿名访问时全部 401/重定向。实测平台的免登白名单极窄,常规业务接口不在其中——即"公开访问一个页面"很容易,让这个页面匿名取到数据才是真难题。
第二重:公开访问配置的限制
平台有"页面公开访问"的分享配置,但实测其免登开关保存即被拦回(接口层校验,配置项形同虚设),且 UI 上没有可用的免登数据源入口。也就是说:公开页能显示静态内容,一旦要查数据就断粮。
第三重:绕行方案的死胡同
试过把镜像数据同步到另一个测试组织再建公开页,结果发现免费版组织的自定义页面配额为零,方案搁置。也评估过自建中转接口直连 OA 开放接口,但等于把鉴权、频控、缓存全部自己扛一遍——能用的时候当然好,可维护成本不划算。
三、最终方案:对象存储快照 + 双通道降级
思路转换:既然平台侧给不了匿名数据通道,就把数据搬到平台外。我自建的对象存储(MinIO,此前写过部署篇)正好补位:
几个设计点:
- 为什么由服务器侧写而不是应用直连对象存储:密钥永远不出服务器;应用侧只持有"读一个固定 key"的公网只读 URL;
- 为什么快照够用:审批单分钟级变化,快照与真实数据的延迟 ≤ 1 个同步周期;保安查询场景完全可接受;
- 脱敏:快照只含查询必需字段(姓名/状态/期限/区域/照片 URL),审批明细、证件号等一概不进快照;
- 实时通道并行保留:登录态用户(管理员、HR)仍然查实时接口,快照只是匿名通道的替身,两不干扰。
四、两个差点翻车的运维坑
坑 1:对象存储客户端静默降级为本地文件系统
最阴险 用 mc 客户端配置别名后,如果配置时的连通性探测失败(比如走了会破坏签名的代理路径),后续的 mb/cp 不会报错,而是静默降级成对本地文件系统的操作——"上传成功",实际上写到了本地磁盘。识别特征:报错或输出里出现对相对路径的 Insufficient permissions to access this path。第一次部署时我盯着"上传成功"的日志很困惑了半天,直到在对象存储侧根本找不到文件。
坑 2:反向代理破坏签名
对象存储的请求签名(SigV4)包含 Host 头。nginx 反代默认改写 Host(取上游服务器名),签名校验直接失败,且报错含混。正解是反代必须原样透传客户端 Host:
location = /snapshot/data.json {
# SigV4 签名含 Host, 透传客户端原始 Host($http_host) 才能校验通过
# 用 $host 会在非标准端口场景丢端口信息, 必失败
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:<内网端口>;
}
# vhost 只留这一条 location, 其余一律 404
五、查询语义:fail-closed 的具体落地
安全类查询必须守住一条线:加载失败 ≠ 查无此人。页面的状态机分四态:正常(有绿章/红章结论)、查无此人(明确提示先去提交审批)、数据加载失败(显式告警,提示按无有效授权处理)、加载中。任何接口异常都归入第三态,绝不落到"未查到"。这条规则听起来保守,实际拦住的坑包括:同步脚本单轮失败、快照过期未更新、公网链路抖动——每一条都可能造成误放行。
六、踩坑清单(可直接复用)
- 公开访问页面 ≠ 公开数据通道:平台登录墙挡的是取数接口,规划匿名需求时先验证数据链路再动手;
- 对象存储快照是最省心的匿名数据方案:固定 key 覆盖写 + 公网只读单路径 + 双通道降级(登录态实时优先);
- 密钥不出服务器:上传由服务器侧完成,应用/公网侧只拿只读结果;
- mc 客户端会静默降级为本地文件系统:别名探测失败后上传"假成功";认准相对路径的权限报错特征,部署后端到端验证;
- nginx 反代对象存储必须透传 Host($http_host):SigV4 签名含 Host,改写即失败;用 $host 在非标端口场景必踩;
- 暴露面收窄到单条 location:其余路径全部 404,快照 key 定期更换文件名前缀也是低成本加固;
- 查询类页面做 fail-closed:加载失败是独立状态,绝不与"查无"合并展示;
- 免费版组织的配额先查再选方案:跨组织绕行的路可能直接死在配额上。
评 论