Cloudflare Workers 如何读取请求头中的真实用户 IP?

文章导读
在 Cloudflare Workers 环境中,获取客户端真实 IP 最推荐的做法是直接读取 request 对象上的 cf 属性(非 HTTP 头),其次信任 CF-Connecting-IP 请求头,避免解析不可控的客户端 header。
📋 目录
  1. 核心代码实现
  2. 部署与调试注意
  3. 验证与故障排查
  4. 参考资料
A A

在 Cloudflare Workers 环境中,获取客户端真实 IP 最推荐的做法是直接读取 request 对象上的 cf 属性(非 HTTP 头),其次信任 CF-Connecting-IP 请求头,避免解析不可控的客户端 header。

先说结论:优先使用 request.cf.ip 属性,其次信任 CF-Connecting-IP 请求头,避免解析不可控的客户端 header。

  • 适合:需要在 Worker 逻辑中记录日志、做频率限制或地理定位的场景。
  • 先看:确认你的 Worker 运行在 Cloudflare 边缘节点,本地模拟环境可能不支持 cf 对象。
  • 建议:同时保留日志备份,以便在 CDN 配置变更时追溯来源。

核心代码实现

Cloudflare 作为反向代理,客户端请求到达 Worker 之前已经过边缘节点。客户端发送的 HTTP 请求头(如 X-Forwarded-For)可被伪造,而 request.cf 对象由 Cloudflare 平台保证,更安全且方便。

JavaScript 版本:

Cloudflare Workers 如何读取请求头中的真实用户 IP?
export default {
  async fetch(request, env, ctx) {
    // 首选:从 cf 对象读取(运行时属性,非 Header)
    const ip = request.cf?.ip;
    
    // 备选:从 Cloudflare 注入的 Header 读取
    const headerIp = request.headers.get('CF-Connecting-IP');
    
    return new Response(`Your IP: ${ip || headerIp}`);
  }
};

TypeScript 版本:
建议安装 @cloudflare/workers-types 以获得完整的类型提示。

import { CfProperties } from '@cloudflare/workers-types';

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise {
    // 类型断言确保 cf 属性可用
    const cf = request.cf as CfProperties | undefined;
    const ip = cf?.ip;
    
    return new Response(`Your IP: ${ip}`);
  }
};

部署与调试注意

1. 创建 Worker:登录 Cloudflare Dashboard,进入 Workers 页面创建或编辑脚本,粘贴上述代码。

2. 本地调试限制:使用 wrangler dev 本地调试时,request.cf 对象可能是模拟的或不存在的。不要依赖本地测试结果作为最终依据,务必部署到边缘节点后验证。

3. 路由配置:若希望特定域名触发该 Worker,需在 Triggers 页面添加路由规则,否则只能通过 workers.dev 域名访问。

Cloudflare Workers 如何读取请求头中的真实用户 IP?

验证与故障排查

1. 命令行验证

在终端执行 curl 命令访问你的 Worker 地址,查看返回内容是否包含 IP 地址:

curl https://your-worker.your-subdomain.workers.dev

响应体应显示类似 Your IP: 203.0.113.1 的格式。如果显示 undefined 或空,说明 cf 对象未生效。

Cloudflare Workers 如何读取请求头中的真实用户 IP?

2. 日志排查

在 Dashboard 的 Workers 页面选择你的 Worker,点击 Logs。如果代码中添加了 console.log(ip),可以在这里看到捕获到的 IP 值。若日志中 cf 对象为空,检查是否已正确部署到生产环境而非仅本地运行。

3. 常见工程问题

  • Header 大小写:虽然 HTTP 头通常不区分大小写,但在代码中建议严格按照 CF-Connecting-IP 书写,或使用 headers.get 方法自动处理。
  • 不要信任 X-Forwarded-For:除非你有特殊的受信代理链路配置,否则在 Cloudflare 后面再接一层自己的服务时,也不要直接透传客户端的 X-Forwarded-For,应继续使用 Cloudflare 注入的头。
  • 计划限制:基础的 IP 地址读取对所有计划开放,但部分高级 IP 地理信息可能需要企业计划支持,不要误以为获取 IP 本身需要付费。

参考资料

  • Cloudflare Developers. "Workers Runtime APIs: Request". URL: https://developers.cloudflare.com/workers/runtime-apis/request/
  • Cloudflare Developers. "HTTP Request Headers". URL: https://developers.cloudflare.com/fundamentals/reference/http-request-headers/