Skip to content

请求头规范

本文档定义了 SlaunchX 后端识别的所有 HTTP 请求头,按来源层分类。作为前端开发者和内部团队的唯一事实来源。

架构概览

请求在到达后端应用之前,会经过四个层:

客户端(浏览器 / API 调用方)
  → Cloudflare(CDN + 边缘安全)
    → Nginx(网关反向代理)
      → Spring Boot(后端应用)

每一层可能注入、透传或剥离请求头。下表按 来源信任级别 对所有请求头进行分类。


L1: 客户端请求头(前端 / API 调用方设置)

这些请求头由调用方显式设置。后端会验证但不会盲目信任。

Web 链路(JWT 认证)

请求头必填描述
Authorization登录流程获取的 Bearer <JWT> 令牌
X-LOCALE应用语言偏好(如 en-USzh-CN
X-Client-Hash条件客户端指纹哈希。在端点启用指纹验证时必填(@GatewayValidation 配合 FingerprintHandler
X-Workspace-Id多工作空间用户的工作空间标识
X-Turnstile-Token条件Cloudflare Turnstile 挑战令牌。在 enableTurnstile=true 的端点必填。替代方式:cf-turnstile-response 查询参数

API 链路(HMAC 认证)

请求头必填描述
X-Api-KeyAPI Key 标识符(如 sk_live_abc123
X-TimestampUnix 时间戳(秒,UTC)。服务端拒绝偏差 > 60 秒的请求
X-Nonce唯一请求标识符(建议使用 UUID v4)。防止重放攻击
X-SignatureHMAC-SHA256 签名,Base64 编码。计算方式参见认证指南
X-LOCALE应用语言偏好

L2: 浏览器自动请求头(透明转发)

这些请求头由浏览器引擎设置,通过 Cloudflare 和 Nginx 原样转发。非浏览器客户端可以伪造。

请求头描述使用方
User-Agent浏览器/客户端标识字符串会话指纹、风控引擎、审计日志
Accept-Language浏览器语言偏好风控引擎上下文
Sec-CH-UAClient Hints:浏览器品牌和版本会话指纹
Sec-CH-UA-PlatformClient Hints:操作系统会话指纹
Sec-CH-UA-MobileClient Hints:移动设备标识(?0?1会话指纹

安全说明:这些请求头参与会话指纹计算(SessionFingerprintExtractor)。登录时的指纹与后续请求不匹配会触发 FINGERPRINT_MISMATCH(错误码 50030101)。


L3: Cloudflare 注入请求头(可信,客户端不可伪造)

这些请求头由 Cloudflare 边缘节点添加。后端将其视为权威来源。客户端无法设置或覆盖这些请求头 — Cloudflare 会剥离任何客户端提供的值。

自动注入(始终存在)

请求头描述
CF-Connecting-IP客户端真实 IP 地址。ClientIpResolver 的首选来源
Cf-RayCloudflare 请求追踪 ID。用于调试和风控审计追踪
Exposed-Credential-Check泄露凭据检测标记。启用 Cloudflare 泄露凭据检测功能后注入

Managed Transform(需在 Cloudflare 控制台配置)

需启用 "Add visitor location headers" Managed Transform。

请求头描述
cf-ipcountryISO 3166-1 alpha-2 国家代码
cf-region区域或省份
cf-ipcity城市
cf-iplatitude纬度坐标
cf-iplongitude经度坐标
cf-postal-code邮编
cf-timezone客户端时区(如 America/Los_Angeles

配置路径:Cloudflare Dashboard > Rules > Transform Rules > Managed Transforms > "Add visitor location headers"。


L4: Nginx 注入请求头(可信,反向代理写入)

这些请求头由网关服务器上的 Nginx 反向代理写入。具有权威性,客户端无法影响。

请求头描述生成方式
X-Real-IP直连 IP(通常是 Cloudflare 边缘 IP)$remote_addr
X-Forwarded-For完整代理链 IP 列表$proxy_add_x_forwarded_for
X-Forwarded-Proto原始请求使用的协议硬编码 https
X-Request-Id唯一请求追踪 ID$msec-$connection-$connection_requests
X-PORTAL-ACCESS-CODE从子域名解析的门户访问码Nginx map 块:子域名 → 访问码

门户访问码映射

X-PORTAL-ACCESS-CODE 不由前端设置。Nginx 根据子域名解析:

system-alpha.slaunchx.cc  → map → $alpha_portal_access_code = "<portal-access-code>"
<tenant>-alpha.slaunchx.cc → map → $alpha_portal_access_code = "<portal-access-code>"

注意:以上示例值为占位符。实际访问码存储在 /etc/nginx/snippets/slaunchx-*-portals.conf 中,不得提交到文档。

后端的 PortalAccessCodeHandler 会根据数据库验证此访问码,确定 portalTypeinstitutionBizId


IP 解析优先级

ClientIpResolver 使用以下优先级链确定客户端真实 IP:

1. CF-Connecting-IP     (L3 — Cloudflare,权威来源)
2. X-Real-IP            (L4 — Nginx,回退)
3. X-Forwarded-For[0]   (L4 — 第一条,无 CF 时可能被伪造)
4. request.getRemoteAddr()(直连 IP,最后手段)

在标准 Cloudflare + Nginx 架构下,CF-Connecting-IP 始终存在且被使用。


代码参考

模块职责
ClientHeaderExtractorslaunchx-infra-gateway-core将 L1/L2/L3 请求头提取到 ClientInfo 记录
ClientIpResolverslaunchx-infra-gateway-coreIP 解析优先级链
SessionFingerprintExtractorslaunchx-infra-gateway-core从请求头构建会话指纹
GatewayRiskContextBuilderslaunchx-infra-risk从所有请求头层构建风控上下文
ValidationContextslaunchx-infra-gateway-core读取 X-Request-IdX-Forwarded-For

安全边界

原则实现方式
L3/L4 请求头可信Cloudflare 和 Nginx 是唯一来源。后端不验证其格式。
L1 请求头需验证JWT 会被验证,HMAC 会被重新计算,Turnstile 令牌会通过 CF API 检查
L2 请求头仅供参考用于指纹和风险评分,从不用于访问控制决策
默认拒绝端点无 @ApiScope = 403。WEB 链路缺少 X-PORTAL-ACCESS-CODE = 门户解析失败
不向客户端转发请求头L3/L4 请求头名称和值永远不会出现在 API 响应中

内部手册