我想记录在Azure上托管的Web应用程序(Symfony 4.1(上的每次登录尝试。
基于这个问题,为了获得客户端IP,我使用:
// $requestStack being SymfonyComponentHttpFoundationRequestStack
$ip = $this->requestStack->getMasterRequest()->getClientIp();
然而,日志显示:
[2020-03-10 10:55:56]登录尝试。信息:用户"username"已从ip"172.16.1.1"[][]成功登录
正如您所注意到的,这是一个私有IP。我试着从不同的连接登录,但我总是得到那个IP,172.16.1.1
。这个IP从哪里来,如何获得客户端真正的公共IP?
私有IP可以是负载均衡器或反向代理。
来自文件:
当您部署应用程序时,您可能在负载均衡器(例如AWS弹性负载平衡(或反向代理(例如用于缓存的Varnish(后面。
在大多数情况下,这不会给Symfony带来任何问题。但是,当请求通过代理时,使用标准
Forwarded
报头或X-Forwarded-*
报头发送某些请求信息例如,用户的真实IP将存储在标准Forwarded: for="..."
标头或X-Forwarded-For
标头中,而不是读取REMOTE_ADDR
标头(现在将是反向代理的IP地址(。如果您不将Symfony配置为查找这些标头,您将获得有关客户端IP地址的错误信息,无论客户端是否通过HTTPS连接、客户端端口和请求的主机名。
要解决此问题,可以在应用程序的受信任代理中添加该IP。
在Symfony 4中,这可以通过以下方式完成:
// index.php
// creates the $_SERVER['TRUSTED_PROXIES'] entry if it doesn't exist/is empty with the IP of the proxy to trust as value
// or append ',the ip' to the existing entry
$_SERVER['TRUSTED_PROXIES'] = (empty($_SERVER['TRUSTED_PROXIES']) ? '' : ($_SERVER['TRUSTED_PROXIES'] . ',')) . '172.16.1.1';
// This is already in index.php, just let it doing its job
if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? false) {
Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
}
现在,在日志中:
[2020-03-10 13:09:06]登录_尝试。信息:用户"username"成功从ip">公共ip地址"[][]登录