Nginx反向代理解决ip获取问题

314 阅读2分钟

任务

有访客记录的需求,所以需要获取客户端IP以及地理位置

image.png
  • 本项目前端使用vue框架,需要通过js调用公共api获取信息

实现

第一想法

直接通过axios发送请求获取信息

await axios.get("https://searchplugin.csdn.net/api/v1/ip/get ",{  
  baseURL:'/ipapi'  
}).then(res => {  
  ip = res.data.data.ip
  region=res.data.data.address
})

当然,不出意料的会造成跨域问题: 本博客域为(www.rocblog.cn) ,而请求的域为 (searchplugin.csdn.net/api/v1/ip/g…) ,访问时理所应当的会造成跨域问题

第二想法

为了解决跨域问题,需要在nginx中做一个反向代理,让前端发送请求给nginx,然后由nginx发送请求给公共api,然后将结果返回给前端。
于是我们将nginx的配置文件nginx.conf做出以下修改

#在对应的server代码块中添加
location /ipapi/ { 
      proxy_pass https://searchplugin.csdn.net/api/; 
} 

然后将前端js请求改为

await axios.get("/v1/ip/get",{  
  baseURL:'/ipapi'  # 将axios的baseUrl改为和nginx服务器中所对应的/ipapi
}).then(res => {  
  ip = res.data.data.ip  
  region=res.data.data.address  
})

axiosbaseUrl改为和nginx服务器中所对应的/ipapi
这样子前端所请求的路径就是www.rocblog.cn/ipapi/v1/ip…
然后nginx会自动将www.rocblog.cn/ipapi 替换为我们刚刚所配置searchplugin.csdn.net/api/ 这样子拼接下来其实就是和searchplugin.csdn.net/api/v1/ip/g… 这个地址一样的。


做完以上处理其实我们的工作就差不多了,可以看到已经可以成功请求了

image.png

但是到记录一看就会发现问题

image.png

这里的ip不是我服务器的ip吗?根本不是真实的客户端ip

稍微一想就很容易明白其中的原因:

  • 因为我们使用nginx代理转发的请求:客户端请求nginxnginx请求公共api。无论客户端怎么改变,真正请求公共api的永远是nginx(我的服务器),公共api获取不到真实的客户端ip。

然后我想清楚了这个问题之后,就去百度了一下:nginx怎么用真实IP发送请求

最终解决问题

其实方法也很简单,将刚刚的转发配置多增加两行配置(由于此处具体为何这样配置比较复杂本文不赘述,后续会专门写一篇讲这个问题。但其实从英文上也可以大致了解一二)

  • proxy_set_header:设置转发的请求头,将真实的客户端ip添加进去
   location /ipapi/ { 
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;    
         proxy_pass https://searchplugin.csdn.net/api/;  
   }

添加后可以看到问题已经解决了

image.png