IP白名单配置后请求仍被拦截,是什么原因?

程序猿利伟 阅读 28

最近在给支付接口配置IP白名单时遇到问题,明明把测试服务器IP加进去了,但前端发起请求还是被返回403。检查过防火墙规则没问题,白名单代码也按文档写了,但就是通不过验证。测试用的是本地开发环境,可能跟Nginx代理有关吗?

后端用的Express中间件配置如下:


const validIps = ['114.51.32.173', '127.0.0.1'];
app.use((req, res, next) => {
  if (!validIps.includes(req.ip)) {
    return res.status(403).send('IP forbidden');
  }
  next();
});

用Postman直接请求接口没问题,但前端页面通过axios请求就拦截。测试时用curl查看发现请求头里的X-Forwarded-For显示的是本地局域网IP,这会不会是真实IP被代理修改导致的?

我来解答 赞 13 收藏
二维码
手机扫码查看
1 条解答
玉泽酱~
这个问题确实挺常见的,尤其是涉及到反向代理的时候。你遇到的情况大概率是因为Nginx代理把真实的客户端IP给“藏”起来了,默认情况下Express的 req.ip 获取到的是代理服务器的IP,而不是客户端的真实IP。

我们一步步来解决这个问题。

第一步:确认问题根源
你提到用Postman请求没问题,但前端通过axios请求就被拦截了,同时发现 X-Forwarded-For 里显示的是本地局域网IP。这里需要注意,X-Forwarded-For 是一个HTTP头字段,通常用来记录客户端的真实IP地址。当请求经过代理时,代理会把客户端的原始IP写入这个字段。

所以问题的关键在于:你的Express中间件在获取IP时,没有正确处理代理传递过来的 X-Forwarded-For 字段,而是直接用了 req.ip,导致验证失败。

第二步:修改Express中间件逻辑
我们需要调整代码,让它优先从 X-Forwarded-For 中提取真实IP,而不是直接使用 req.ip。可以这样改:


const validIps = ['114.51.32.173', '127.0.0.1'];

app.use((req, res, next) => {
// 获取客户端的真实IP,优先从 X-Forwarded-For 中提取
let clientIp = req.headers['x-forwarded-for'];

// 如果 X-Forwarded-For 存在,取第一个IP(最原始的客户端IP)
if (clientIp) {
clientIp = clientIp.split(',')[0].trim();
} else {
// 如果不存在,则回退到 req.ip
clientIp = req.ip;
}

// 检查IP是否在白名单中
if (!validIps.includes(clientIp)) {
return res.status(403).send('IP forbidden');
}

next();
});


这段代码的核心是:
1. 先检查 X-Forwarded-For 是否存在,如果存在就提取第一个IP(因为这个字段可能包含多个IP,以逗号分隔)。
2. 如果 X-Forwarded-For 不存在,再回退到 req.ip
3. 这样就能保证无论请求是否经过代理,都能拿到正确的客户端IP。

第三步:配置Nginx信任代理
如果你用的是Nginx作为反向代理,还需要确保Nginx正确设置了 X-Forwarded-For 头部。默认情况下Nginx不会自动添加这个头部,需要手动配置。

打开你的Nginx配置文件,找到对应的服务块,添加以下内容:


server {
listen 80;
server_name yourdomain.com;

location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://localhost:3000; # 假设后端运行在3000端口
}
}


这里的 $proxy_add_x_forwarded_for 是Nginx的一个内置变量,它会自动追加客户端的真实IP到 X-Forwarded-For 中。

第四步:测试和验证
完成以上修改后,记得重启Nginx和Express服务:

- 重启Nginx:运行 sudo systemctl restart nginx
- 重启Express:根据你的启动方式重启服务

然后再次通过前端页面发起请求,看看是否还会被拦截。如果问题解决了,说明我们的改动生效了。

额外提醒
1. 如果你的服务部署在云平台上(比如AWS、阿里云等),有些云负载均衡器也会修改 X-Forwarded-For 的值,这时候需要查阅对应平台的文档,确保代理链路中每个环节都正确传递了客户端IP。
2. 白名单中的IP最好是固定IP,动态IP可能会导致频繁更新白名单。

希望这些步骤能帮你解决问题!如果有其他疑问,随时问。
点赞
2026-02-17 18:00