【问题标题】:How do I get the user IP address in Symfony2 controller?如何在 Symfony2 控制器中获取用户 IP 地址?
【发布时间】:2012-02-20 05:36:09
【问题描述】:

我需要在提交表单后将评论用户的IP地址存储在数据库中。

symfony2 有没有获取 IP 的函数?或者其他方式获取IP?

【问题讨论】:

    标签: symfony ip-address


    【解决方案1】:

    您可以使用请求服务获取客户端 IP:

    $container->get('request')->getClientIp();
    

    【讨论】:

    • 感谢您的快速回复。我可以知道 $container 是从哪里来的吗?
    • 好的,这样就可以了:$ip = $this->container->get('request')->getClientIp();
    • 注意,最好直接使用注入的$request,而不是从容器中抓取,所以只需使用$request->getClientIp()就足够了
    【解决方案2】:

    仅供参考,从 Symfony 2.0 Request::getClientIp 开始,$proxy parameterdeprecated。它将在 Symfony 2.3 中删除

    你可以使用

    $container->get('request')->server->get("REMOTE_ADDR");
    

    或@meze 回答

    $container->get('request')->getClientIp();
    

    【讨论】:

    • 只有 getClientIp 的“代理”参数已被弃用。 github.com/symfony/symfony/compare/922c201...e5536f0.patch
    • 我从不推荐使用REMOTE_ADDR。它可能在您的开发机器上本地运行,但如果您的生产应用程序前面有任何类型的反向代理或负载均衡器,您的代码将会中断。 getClientIp() 是在 Symfony 中获取客户 IP 的唯一可靠方法。
    【解决方案3】:

    在 Symfony 2.3 之前 $this->container->get('request')->getClientIp() 仅在主请求控制器内部有效。在子请求控制器中,这总是返回127.0.0.1。如果您的项目使用 Symfony 2.2 的子请求,防弹解决方案是创建 kernel.request 侦听器并将主请求的 IP 保存在其中。

    在 Symfony 2.3 中,此问题已修复,因此对于内部子请求,真实 IP 被推送到代理列表,请参阅 https://github.com/symfony/symfony/commit/2f3b33a630727cbc9cf21262817240a72a8dae0c 所以你需要在 Symfony 2.3+ 的子请求中添加 127.0.0.1trusted_proxies 配置参数来获取客户端 ip,但是出于安全原因你不应该在共享主机上这样做。

    此外,如果在 Symfony 2.3.20 之前使用内置 HTTP 缓存(AppCache in web/app.php),则必须将 127.0.0.1 显式添加到 trusted_proxies。这个缓存试图看起来像一个真正的反向代理,并修改了一些主请求的标头。修复于https://github.com/symfony/symfony/commit/902efb8a84e8f0acf6a63e09afa08e3dcdd80fb9

    从 Symfony 2.43.x 开始,访问当前请求的首选方式是使用 request_stack 服务

    $this->container->get('request_stack')->getCurrentRequest()->getClientIp();
    

    或将Request注入控制器,见http://symfony.com/doc/current/book/controller.html#the-request-as-a-controller-argument

    public function indexAction(Request $request)
    {
        $ip = $request->getClientIp();
    }
    

    但在子请求中使用时排除 127.0.0.1 的问题仍然存在,但现在您可以尝试使用显式引用主请求

    $this->container->get('request_stack')->getMasterRequest()->getClientIp();
    

    【讨论】:

    • 我正在使用 Symfony 2.3.11,但我的子请求仍然返回 127.0.0.1(我们不打算使用内置缓存),所以在我看来它还没有修复。
    • @Shinhan 我查看了相关代码,发现他们接受了另一种方法。现在内部子请求的工作方式应该与内部 HTTP 缓存相同。我已更新答案,但尚未测试解决方案。
    • 还有一个始终信任 127.0.0.1 的开放请求:github.com/symfony/symfony/issues/9292
    • 我得到 10.0.2.2 我不认为这真的是我的 ip。我在本地机器上测试,也许我应该在线测试?
    • @JoeYahchouchi 在本地或虚拟网络中这是一个完全有效的 IP,但如果您在真实网站上获得此 IP,则应咨询您的托管服务提供商以了解他们的反向代理设置。
    【解决方案4】:

    对于 Symfony 2.6+,使用以下代码(在您的控制器中:

          $this->container->get('request_stack')->getCurrentRequest()->getClientIp();
    

    【讨论】:

      【解决方案5】:

      还有另一种方法可以将当前客户端 IP 注入到任何服务或方法调用中:

      acme.currentIP:
          class: some\service\className
          arguments:
              - "@=service('request_stack').getCurrentRequest().getClientIp()"
      

      【讨论】:

      • 这是一个不好的方法。更好地自己注入请求堆栈并在构造函数中获取 ip
      • @Sharpy35 没有理由避免这种方法,我怀疑客户端的IP在请求期间发生了变化?
      • 我不明白这种方法是如何工作的。服务是在请求进入之前构建(和缓存)的。
      • 不,这段代码描述了服务将如何构建,所以在请求进来后调用。
      猜你喜欢
      • 2014-05-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-04
      • 1970-01-01
      • 2017-10-15
      • 2020-10-18
      • 2010-10-25
      • 2011-06-02
      相关资源
      最近更新 更多