Proxy 与 Namespace:终结环境与鉴权的噩梦
本章基于基础事实来讲述NameSpace的重要性
图注:所有前端请求在这里统一安检、分流,走向正确的后端服务。
开场故事:被"环境标"与 Cookie 折磨的前端
在没有统一 BFF 的时代,一个前端工程师的日常,常常伴随着一些令人抓狂的场景:
"小王,我本地环境起不来,访问你的接口报跨域了,你那能开一下 CORS 吗?" "李工,麻烦问下,我要联调用户中心的 PPE 环境,请求头里要加哪个环境标来着?是
X-TT-ENV还是X-TT-PPE?" "奇怪,我明明在测试环境,为什么创建的订单会出现在线上数据库里?!"
这些问题听起来琐碎,却像慢性毒药一样,日复一日地消耗着前端团队的精力和耐心。
问题摊牌:环境与鉴权的无底洞
这些混乱现象的背后,是几个长期困扰前端的根源性问题:
- 环境标的迷宫:后端微服务通常有多套环境:本地、测试、预发布(PPE)、灰度、生产。为了在本地开发时能联调到正确的后端服务,前端不得不在代码里写死后端的 IP,或是在请求工具里手动塞入各种环境标。一旦不小心把带有测试环境标的代码发布到线上,就可能酿成严重的生产事故。
- 跨域与鉴权的无底洞 :前端页面部署在
a.company.com,却要调用user.company.com和order.company.com的接口。为了解决跨域,前端不得不与各种Access-Control-Allow-Origin配置斗智斗勇。更糟糕的是鉴权,每个前端项目都得复制粘贴一套逻辑去解析 Token、判断登录态、处理会话过期,并小心翼翼地将凭证附带在每一个发往不同域的微服务请求上。 - "邻居的噪音":公司内部往往有多个业务线(如 C 端商城、B 端中台、内部运营系统),它们可能共享同一套底层微服务。如果 B 端系统在测试时修改了某个全局配置,正在开发的 C 端系统就可能莫名其妙地报错。团队之间缺乏有效的逻辑隔离,互相干扰成为常态。
解法白话:构建带有多租户隔离的"智能防线"
为了彻底终结这场噩梦,笔者在 BFF 中引入了两个最基础也最重要的模块:Proxy (统一代理) 和 Namespace (命名空间)。
笔者的设计思路非常明确:让前端变得绝对"无脑"。
前端工程师只需要向同域名的 BFF 发起最普通的 HTTP 请求,不关心目标服务的真实地址,不关心当前是什么环境,也不用操心如何携带 Token。剩下的所有脏活累活------鉴权、环境路由映射、协议转换、凭证注入------全部由 BFF 在后台悄无声息地完成。
图注:每个 Namespace 如同独立的办公区,拥有自己的门禁和访客规则。
同时,笔者引入了"命名空间 (Namespace)"的概念,实现了多租户隔离,并将不同的业务线(或客户)划分到独立的 Namespace 中。每个 Namespace 拥有自己独立的认证模式 (AuthMode)、独立的路由元数据 (RouteMeta) 和独立的微服务版本映射。这就像为每个团队分配了专属的、隔音的办公室,互不打扰。
技术展开:拦截、查表、注入与透传
在代码实现上,这套机制如同一条精密的流水线,优雅地处理着每一笔前端请求:
-
路由与元数据映射 (RouteMeta) : 前端发起的请求路径通常被设计为一种约定格式,例如
/proxy/:namespace/:service/:method。当这样的请求到达 BFF 的ProxyController时,BFF 首先会根据:namespace和:service去数据库(或 Redis 缓存)中查找RouteMeta。这一步确保了系统只代理那些真正在 BFF 注册过的、合法的接口,有效防止了恶意扫描。同时,BFF 会从元数据中获取目标微服务真实的BaseUrl和内部 RPC 路径。 -
鉴权清洗与注入 (AuthGuard) : 请求在进入代理转发逻辑前,会先经过一道严格的鉴权守卫
AuthGuard。BFF 会提取前端请求中携带的 Token,不仅验证其签名和有效期,还会查询 Redis 中的用户会话(Session)以确认其真实性。 关键动作 :BFF 在这一步会将外部传入的、可能不安全的凭证(如 Cookie、原始 Token)彻底"清洗"掉。然后,在转发给后端微服务的请求头中,极其确定地注入一个X-USER-ID。这样一来,下游的微服务彻底解放,它们不再需要关心"如何解密 Token",只要读取请求头里的X-USER-ID,就可以百分之百地信任这个请求的身份。 -
环境标的智能注入 : 对于多环境路由,BFF 实现了完全的自动化。如果运维或开发同学在 BFF 的管理后台将当前 Namespace 的环境切换到了 PPE,那么 BFF 在代理转发时,会自动在请求头中打上
X-TT-ENV=ppe的标签。前端代码一行环境变量都不用修改,就能在各套测试环境间无缝漫游,彻底告别手动维护环境配置的痛苦。 -
微服务版本的灵活切换: 不同于传统方案中微服务版本被硬编码在前端配置里,BFF 支持在管理后aps.bytdiance.com台上动态配置每个 Namespace 下各微服务的版本。这意味着同一个前端应用,在不同的 Namespace 下,可以自动调度到完全不同的微服务实例。A 客户使用的是 v2.3.1 版本的用户服务,B 客户可能已经在体验 v2.4.0 了,而这种版本差异对前端完全透明。
-
跨域的彻底消解: 由于所有的前端请求都先打到同域的 BFF,再由 BFF 转发到各个微服务,浏览器根本感知不到跨域的存在。CORS 配置从此不再是前端的噩梦,后端微服务也无需各自配置 CORS 头,BFF 统一处理。
一句话总结
Proxy 模块是 BFF 的"万能翻译官",把前端发送的约定式请求,精准地翻译成后端微服务期望的 RPC 调用。
Namespace 模块是 BFF 的"空间隔离官",确保不同租户、不同业务线的配置与权限老死不相往来。
有了这两道防线,前端终于可以安心写业务,后端也能专注写服务,运维更是从此告别"环境噩梦"。
接下来笔者会开始着重讲解NmaeSpace的细节逻辑