Nginx代理背后Yii2如何获取玩家的ip地址
前两天为了装高大上以及负载均衡,然后给我的网站做了一个前端代理。于是后端服务器拿到的全是代理服务器的ip访问地址。
用户 <----->负载均衡服务器 <------>web服务器
因为负载均衡服务器,代替了玩家的请求,于是造成了web服务器拿到的是负载均衡的ip,而不是玩家的真实ip地址。
那么怎么处理呢?方法百度了一下,方案很多,但是如果百度后直接上去做,就会大概率。。。不奏效。
先说解决方案的原理吧,原理弄清楚了,后面解决方法也就清晰了。
第一:我们要明白服务器一般是怎么拿到玩家的ip地址的?
没有代理的情况下,用户和web服务器直接通信,既然是直接通信,那么通过remote的ip地址,自然而然就是用户的ip地址。
第二:负载均衡的服务器中间做了什么?
负载均衡的服务器,其实为了平衡后端web服务器的压力,把大量的请求分给不同的web服务器处理,变成了一个中间人代替用户访问网站,然后把访问到的数据再返回给用户。所以web服务器在通过remote的ip地址拿到的就是负载均衡服务器的ip地址。
当明白问题参数的原因后,我们需要解决,如何让代理服务器把玩家的ip地址传给web服务器呢?肯定是不能修改自己的ip地址,因为他要代理各种ip地址的玩家,所以我们需要通过一个协议跟web服务器沟通,我应该把数据放到哪儿,然后你去哪儿去取就行了。所以通用的解决方案是代理服务器把玩家的ip地址封装到转发的请求的web协议的请求头Header中。然后web服务器此时通过header中的字段获取玩家的ip,而不是通过remote的ip地址。
原理搞清楚了。我们开始实施吧。
第一步:代理服务器(负载均衡服务器)把用户的ip放到转发请求的header中。配置如下:
location / {
...
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
第二步:配置web服务器端的程序,告诉yii框架从哪个字段里面获取ip地址。
'components' => [
//....
'request' => [
'csrfParam' => '_csrf-frontend',
'trustedHosts' => [
'1.2.3.4/24' => [ //代理服务器的地址,以及存放用户ip地址的header字段名称。只相信这些主机配置的头字段
'X_REAL_IP',
'X-Forwarded-For'
],
],
'secureHeaders' => [ //这些字段是协议安全有效的,参考 https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
'X-Forwarded-For',
'X-Forwarded-Host',
'X_REAL_IP',
'X-Forwarded-Proto',
'X-Proxy-User-Ip',
'Front-End-Https',
],
'ipHeaders' => [//存放真实用户ip的字段
'X-Forwarded-For', // Common
'X_REAL_IP',
],
'secureProtocolHeaders' => [//存放代理协议的字段
'X-Forwarded-Proto' => ['https'], // Common
// 'Front-End-Https' => ['on']
],
],
],
....
ok! 完毕。。。