4、租户标识解析:域名解析、请求头解析、JWT解析、路径参数解析

在多租户 SaaS 架构中,网关或应用层接收到请求后,首要任务是从请求中提取租户标识(Tenant ID)。租户标识的解析方式直接决定了鉴权拦截链路的入口设计。常见的解析策略包括:域名解析、请求头解析、JWT 解析和路径参数解析。每种方式在隔离性、易用性和安全性上各有侧重。

设计原则:租户标识解析应发生在请求进入业务逻辑之前,通常在 API 网关或中间件层完成。解析后的租户 ID 应注入请求上下文(如 Request Context),供后续鉴权、数据隔离和路由使用。

4.1 四种解析方式对比

解析方式 识别载体 隔离级别 部署复杂度 典型场景
域名解析 Host / SNI 高(物理/逻辑隔离) 中(需 DNS 配置) 大型企业租户、独立域名客户
请求头解析 X-Tenant-ID / Custom Header 中(依赖客户端规范) 低(网关配置即可) API 网关、微服务间调用
JWT 解析 JWT Payload (claims) 高(自带签名防篡改) 低(认证服务签发) 单点登录、移动端、前后端分离
路径参数解析 URL Path (/api/{tenant_id}/...) 低(易泄露、难迁移) 低(路由规则简单) 早期 SaaS、内部管理工具

4.2 域名解析(Host-based Resolution)

客户端通过不同的域名访问 SaaS 服务,网关根据 HTTP Host 头或 TLS SNI 提取租户标识。例如:tenant-a.example.com 和 tenant-b.example.com 分别对应不同的租户。

  • 优势:租户隔离性最强,支持独立 SSL 证书,便于租户自定义域名。
  • 劣势:需要 DNS 管理和泛域名证书支持;租户数量大时域名管理成本上升。
  • 实现要点:网关维护域名到租户 ID 的映射表(可缓存),解析失败时返回 400/404。
网关伪代码示例:
// 基于 Host 头解析租户
String host = request.getHeader("Host");
String tenantId = tenantDomainMap.get(host);
if (tenantId == null) {
    throw new TenantNotFoundException("Unknown domain: " + host);
}
context.setTenantId(tenantId);

4.3 请求头解析(Header-based Resolution)

客户端在 HTTP 请求中携带自定义头部,如 X-Tenant-ID: tenant_123。网关或中间件直接读取该头部值作为租户标识。

  • 优势:实现简单,不依赖 DNS,适合微服务间内部调用。
  • 劣势:依赖客户端正确传递头部,存在被伪造的风险(需结合签名或内部网络隔离)。
  • 安全增强:在网关层对头部进行校验或剥离外部请求中的敏感头部。
安全警告:切勿直接信任来自客户端的 X-Tenant-ID 头部。生产环境中应结合 JWT 签名或内部服务网格 mTLS 验证请求来源合法性。

4.4 JWT 解析(JWT-based Resolution)

租户标识嵌入在 JWT 的 Payload 中,通常放在 tenant_id 或 org_id 字段。网关验证 JWT 签名后,从 claims 中提取租户 ID。

  • 优势:防篡改(HMAC/RSA 签名),可同时携带用户角色、权限等附加信息,适合分布式认证。
  • 劣势:JWT 体积较大,解析有轻微性能开销;需维护密钥管理。
  • 实现要点:网关需缓存公钥或对称密钥,避免每次请求都远程验证。
JWT Payload 示例:
{
  "sub": "user_456",
  "tenant_id": "tenant_abc",
  "role": "admin",
  "exp": 1718000000
}

4.5 路径参数解析(Path-based Resolution)

租户 ID 作为 URL 路径的一部分,例如:/api/v1/tenant_abc/orders。网关通过路由模板匹配提取路径中的租户参数。

  • 优势:路由规则直观,适合快速原型或内部工具。
  • 劣势:租户 ID 暴露在 URL 中,容易在日志、浏览器历史中泄露;路径变更影响所有租户。
  • 适用场景:管理后台、非面向终端用户的内部服务。
最佳实践:尽量避免在公网 API 中使用路径参数传递租户 ID。如果必须使用,建议结合 HTTPS 和短时效 Token 降低泄露风险。

4.6 租户标识解析链路架构

下图展示了请求从客户端到达网关后,经过四种解析策略提取租户 ID,并注入到下游服务的完整链路。

租户标识解析链路架构图 租户标识解析链路架构 客户端请求 API 网关 / 中间件 域名解析 (Host) 请求头解析 (Header) JWT 解析 (Claims) 路径参数解析 (Path) 租户 ID 注入请求上下文 下游业务服务 说明:网关根据配置选择一种或组合解析策略,提取租户 ID 后注入上下文,下游服务无需重复解析。

4.7 组合策略与最佳实践

在实际生产环境中,往往不是单一策略,而是组合使用。例如:外部请求通过域名解析识别租户,内部微服务间通过 JWT 传递租户 ID,同时网关在转发时自动添加 X-Tenant-ID 头部供下游使用。

推荐组合策略:
  1. 外部入口:域名解析 + HTTPS(强隔离)
  2. 认证阶段:JWT 解析(防篡改,携带租户与用户信息)
  3. 内部转发:请求头解析(X-Tenant-ID,轻量高效)
  4. 兜底/兼容:路径参数解析(仅限管理后台或内部工具)

下表总结了四种解析方式在关键维度上的差异,帮助架构师根据业务场景做出选择:

维度 域名解析 请求头解析 JWT 解析 路径参数解析
防篡改能力 中(依赖 DNS 安全) 低(需额外签名) 高(签名验证) 低(明文暴露)
性能开销 低(缓存映射) 极低(读取头部) 中(签名验证) 极低(路由匹配)
租户迁移成本 高(需变更 DNS) 低(客户端更新头部) 低(重新签发 Token) 高(URL 变更)
日志泄露风险 低(域名在日志中常见) 中(需脱敏头部) 低(Payload 可加密) 高(URL 明文记录)
关键提醒:无论采用哪种解析方式,租户 ID 提取后必须进行合法性校验(如格式验证、白名单检查),防止恶意请求通过伪造租户 ID 越权访问其他租户数据。