信息发布→ 登录 注册 退出

Swoole怎么在Nginx后获取WebSocket的真实IP

发布时间:2025-10-02

点击量:
答案:通过Nginx配置传递真实IP并在Swoole中读取X-Real-IP头部可获取客户端真实IP。具体步骤为:1. Nginx配置proxy_set_header X-Real-IP $remote_addr,正确转发WebSocket请求;2. Swoole在on('open')中通过$request->header['x-real-ip']获取IP;3. 为防伪造,应限制Swoole仅监听内网并确保Nginx处于可信环境。

在使用 Swoole 配合 Nginx 做 WebSocket 服务时,直接通过 Swoole 获取客户端 IP 会得到 Nginx 的 IP(比如 127.0.0.1),而不是真实用户 IP。这是因为 Nginx 作为反向代理转发了连接。要获取真实客户端 IP,需要 Nginx 正确传递来源地址,并在 Swoole 中读取对应信息。

1. 配置 Nginx 传递真实 IP

Nginx 必须设置 proxy_set_header 将客户端真实 IP 写入请求头,常用的是 X-Real-IPX-Forwarded-For。同时,在代理 WebSocket 时要正确升级协议。

示例 Nginx 配置:
location /ws/ {
    proxy_pass http://127.0.0.1:9501;  # 转发到 Swoole 服务
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
}

其中 $remote_addr 是 Nginx 拿到的真实客户端 IP,X-Real-IP 是最干净的字段,推荐使用。

2. 在 Swoole 中获取真实 IP

Swoole 接收到 WebSocket 握手请求时,可以通过 request()->header 获取 Nginx 传来的头部信息。不能直接用 $server->connection_info() 的 remote_ip,因为那是与 Nginx 的连接 IP。

PHP 示例代码:
$server = new Swoole\WebSocket\Server("0.0.0.0", 9501);

$server->on('open', function ($server, $req) { $realIp = $req->header['x-real-ip'] ?? $req->server['remote_addr']; echo "Client connected from real IP: {$realIp}\n"; });

$server->on('message', function ($server, $frame) { $server->push($frame->fd, "Hello, {$frame->data}"); });

$server->start();

这里优先从 x-real-ip 头部取值,如果不存在再回退到连接 IP(适用于直连调试)。

3. 安全建议:防止伪造 IP

用户可能伪造 X-Real-IP 请求头,因此只应信任来自 Nginx 的代理。确保:

  • Swoole 服务监听 127.0.0.1 或内网 IP,不对外暴露
  • Nginx 位于可信网络或做了访问控制
  • 生产环境避免使用未验证的 X-Forwarded-For,它更容易被篡改

基本上就这些。只要 Nginx 正确传头,Swoole 按 header 取值,就能拿到真实 IP。

标签:# php  # nginx  # websocket  # proxy  # swoole  # for  # 客户端  # 并在  # 内网  # 的是  # 那是  # 就能  # 推荐使用  # 适用于  # 可以通过  # 不存在  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!