EdgeOne加速Vercel获取真实用户IP

问题复现

使用Vercel部署的Twikoo并且启用了EdgeOne加速,开启了海内外分流,出现无法获取用户真实IP的问题,获取到的是CDN的IP。

问题根源

Vercel Hobby/Pro 会过滤、重写外部传入的 HTTP 头:

  1. EO‑Connecting‑IP:EO 内置头,Vercel 直接丢弃
  2. X‑Forwarded‑For:Vercel 会重写覆盖,只能拿到 EO 节点 IP,所以 TwikooIP 属地错误

解决方案

EdgeOne 控制台配置

使用「真实客户端 IP 头部」:

  • 开关打开
  • 头部名称Eo‑Client‑Ip
  • 保存,等待 2‑5 分钟配置全网生效

EO 会自动把访客真实 IP 填入这个自定义头部,不需要手动写变量。

Vercel‑Twikoo 配置

  1. 环境变量 TWIKOO_IP_HEADERS 值(严格复制,小写 + 合法 JSON)
["headers.eo-client-ip"]
  1. 保存环境变量后必须点 Redeploy 重新部署 Vercel 项目,只保存不部署不会生效。

场景:分流

架构:

  1. 国内用户 → EdgeOne CDN → Vercel:请求携带自定义头 eo‑client‑ip
  2. 海外用户:绕过 EdgeOne,直接访问 Vercel:不会携带 eo‑client‑ip,此时 Vercel 原生提供 x‑forwarded‑for 拿到访客真实 IPVercel

Twikoo 的TWIKOO_IP_HEADERS支持数组多表头,按顺序优先读取:数组写两个,优先读第一个;为空就自动往下读第二个。

  1. 国内访问域名(走 EdgeOne)
{"eo-client-ip":"你的国内公网IP","x-forwarded-for":"EO节点IP"}

Twikoo 优先读取eo‑client‑ip正确 IP。

  1. 海外环境直连 Vercel 域名(不走 EdgeOne)
{"eo-client-ip":undefined,"x-forwarded-for":"海外访客真实IP"}

eo‑client‑ip为空,自动降级读取x‑forwarded‑for拿到真实 IP。

注意事项

  1. 只有海外请求绕过 EdgeOne 直接访问 Vercel的时候,x‑forwarded‑for才是可信真实 IP; 国内走 EdgeOne 的流量,Vercel 会重写 XFF,XFF 拿到的是 EO 节点 IP,所以数组顺序必须 eo‑client‑ip 放第一位
  2. 修改 Vercel 环境变量,必须 Redeploy 重新构建
  3. EdgeOne 配置修改要等待 2‑5 分钟生效。