【问题标题】:How to let Symfony 2 adopt the protocol scheme (http vs https)如何让 Symfony 2 采用协议方案(http vs https)
【发布时间】:2015-04-05 21:25:14
【问题描述】:

我有一个 Symfony 2 网站,在开发中运行在 HTTP 上,或者在生产中运行在 HTTPS 上。

我注意到在生产中,由 Symfony 生成的 URL 仍然全部呈现为 HTTP。

我该怎么做;

  1. 让框架采用为网站提供服务的当前协议(可能是首选)?
  2. 或者,仅在生产环境中强制整个网站采用 HTTPS 模式?

【问题讨论】:

  • 如何生成 URL?与{{ path() }}?
  • 我在 Twig 模板中使用 {{ url(' ... ') }}

标签: php http symfony https


【解决方案1】:

要在您的生产环境中强制使用HTTPS,您可以使用以下配置:

  1. 在你的app/config/routing.yml:

    acme_hello:
        resource: "@AcmeHelloBundle/Resources/config/routing.yml"
        schemes: [https]
    
  2. 在你添加app/config/routing_dev.yml:

    _main:
        resource: routing.yml
        schemes: [http]
    

    如果您想为开发环境中的所有路由强制使用HTTP

  3. 您可以在@AcmeHelloBundle/Resources/config/routing.yml 中放置所有路线。

有关schemes: [https] 的更多信息以及其他使其工作的方法,您可以查看Symfony documentation

【讨论】:

  • 好的。那可能行得通。但是,当将其添加到 resource 时,就像您说明的那样,似乎对我不起作用(缓存已清除)。这绝对是必须由框架配置控制的东西,而不是单独的包。
  • @Luke Symfony2 文档说 Symfony 会自动生成一个使用 HTTPS 作为方案的绝对 URL,它对你有用吗?那么这句话 path with HTTP [...] 将自动重定向到相同的 URL [...] with HTTPS scheme 怎么样?
  • 不幸的是,这似乎对我不起作用。我开始怀疑它可能必须这样做,因为我在负载平衡器或其他东西后面。请理解,并不是该站点不能在 HTTPS 上运行,而是可以。只是模板中生成的 URL 是 HTTP,而它们应该是 HTTPS。
【解决方案2】:

我使用这个解决方案来强制使用 HTTP 或 HTTPS:

我在不同环境的配置文件中定义了一个%auth_required_channel%的值:

app/config/config_dev.ymlapp/config/config_test.yml

parameters:
    auth_required_channel: 'http'

app/config/config_prod.yml

parameters:
    auth_required_channel: 'https'

app/config/security.yml

此参数随后用于要求 HTTP 或 HTTPS 通道 (Symfony2 documentation):

security:
    [...]
    access_control:
        [...]
        - { path: ^/admin, roles: ROLE_ADMIN, requires_channel: %auth_required_channel% }

(改编自old answer

【讨论】:

  • 这只会在安全端点上强制执行协议。我需要在整个网站上强制执行。问题也不在于执行协议,而是生成了不正确的 URL。 IE。我强制使用 HTTPS,但它仍在生成基于 HTTP 的 URL。
  • 那么你必须为security.access_control下的每一行复制, requires_channel: %auth_required_channel%。你有这么多规矩吗? 生成的 URL 不正确 IIRC,使用{{ path(...) }} 生成的 URL 是相对的,因此不会包含协议。 Symfony2 应该将 URL 从 http:// 重定向到 https://
  • 你不懂。您的答案仅适用于为安全捆绑包指定的路由,而不适用于我网站中的其他路由(即routing.yml)。我确定您的示例有效,但它仅适用于安全部分中定义的那些路由,没有别的。
  • 您的答案仅适用于为安全捆绑包指定的路由 防火墙将规则应用于所有规则,它未链接到捆绑包。我不知道路由器是否知道路由是使用 HTTP 还是 HTTPS 通道。无论如何,我刚刚检查了这段代码,Symfony2 在 prod 环境中将请求从 http://... 重定向到 https://...
  • 好的。然后使用安全设置,如何将我网站上的所有路由强制为 HTTPS。不只是/admin 背后的人?
【解决方案3】:

@A.L 和 @AndreySobkanyuk 提供的两种解决方案都有效,但不适用于我遇到的问题。

@A.L 和@AndreySobkanyuk 给出的两种解决方案的问题在于 Symfony 2 正在尝试进行重定向。 IE。如果通过在路由配置中指定不同的协议(例如 HTTP)访问 URL(例如 HTTPS),Symfony 2 将执行重定向(在 PHP 级别)。

在我的情况下,URL 重写发生在 Web 服务器级别 (Apache),因为我的网站将所有 URL 都作为 HTTPS 提供。

我正在处理的问题是,在我的模板中生成的 URL 都是使用 HTTP 协议呈现的,如果它们应该是 HTTPS。我假设有一种方法可以告诉 Symfony,每当它呈现一个 URL 以使用 HTTPS 而不是 HTTP 作为前缀时。不幸的是,没有(或者至少,我没有意识到)。

由于我的网站在负载均衡器后面运行,我的 Web 服务器不知道它应该将 URL 呈现为 HTTPS,因为负载均衡器和 Web 服务器之间的内部连接是 HTTP。这意味着从 Symfony 的角​​度来看,所有请求都是使用 HTTP 发出的,并且通过在 Symfony 路由级别上强制协议,它会导致无限重定向循环,即;

  1. 您通过 HTTPS 访问了一个 URL。
  2. 负载平衡器将请求作为 HTTP 传递给 Web 服务器。
  3. 在 Symfony 中,路由被配置为使用 HTTPS,这会导致 PHP 级别的重定向。
  4. 回到 1(无限循环)。

为了解决我的问题,我必须让我的网络服务器知道我的网站是在 HTTPS 中运行的。按照How to Configure Symfony to Work behind a Load Balancer or a Reverse Proxy 页面上给出的说明,我能够解决问题,即我的 Web 服务器现在提供了正确的标头信息,现在正在生成正确的 URL。

将所需标头从负载平衡器传递到 Web 服务器的最简单方法是将以下行添加到您的 web/app.php

Request::setTrustedProxies(array($request->server->get('REMOTE_ADDR')));

请注意,以上可能不是您特定配置的最佳解决方案。有关可能更适合您的设置的其他方法,请参阅文档。

【讨论】:

  • 我总是在发布我的答案之前测试代码,所以我检查了schemes: [https]resource,它对我很有用。
  • 我所有使用{{ url() }}生成的ulr都是基于https的。
  • @AndreySobkanyuk;你在负载均衡器后面吗?它可能对您有用,因为您不在负载均衡器后面。在我理解这个问题之前,我假设您的解决方案强制呈现 HTTPS URL,但事实并非如此。当使用 HTTP 访问 URL 时,它会强制在 PHP 级别重定向到 HTTPS URL,对我来说,这导致了无限的重定向循环。
  • 很遗憾,我无法为您的负载均衡器提供帮助,这是另一个问题。当然,当您尝试访问基于http 的网址时,Symfony 会尝试重定向您。 但是 至少正如我已经说过的,如果您使用我的解决方案,您使用url() 扩展生成的网址必须基于https。如果您的网址不是基于https,那么您做错了。
  • 是的,接缝我们​​正在回答不同的问题 :) 无论如何很高兴你有解决方案。
【解决方案4】:

我发现这对我的案例很有用(使用 nginx

添加到 nginx fcgi 参数以下行,这是必需的,因为 Symfony2 依赖于这个变量,由 Web 服务器传递给 PHP,以生成正确的 URL。 Apache 默认会这样做,但是 nginx 需要这个特殊的配置

fastcgi_param HTTPS on;

http://blog.servergrove.com/2011/04/04/symfony2-quick-tip-generateurl-with-https-on-nginx/

【讨论】:

    【解决方案5】:

    假设这种情况:

    • 您的 Symfony 应用位于 Varnish 或 BigIP 等反向代理之后
    • 您想将原始客户端 IP 用作 REMOTE_ADDR(即带有 mod_rpaf apache 扩展名)(当然在这种情况下您不能使用 trusted_proxies 值)

    您可以在您的网络服务器中设置 HTTPS 环境变量,索引 X-FORWARDED-PROTO 标头值,以强制 Symfony 使用 https 协议。

    在 Apache 中:

    SetEnvIf x-forwarded-proto https HTTPS=on
    

    【讨论】:

      【解决方案6】:

      如果您想在反向代理/负载平衡器后面使用 https 并在 https 方案中渲染 url / 资产,那么在深入研究之后,您必须同时转发 schemeport

      示例反向代理app.php

      Request::setTrustedProxies(array('127.0.0.1), Request::HEADER_X_FORWARDED_ALL);
      
              proxy_pass                           http://localhost:6081;
              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_set_header  X-Forwarded-Proto $scheme;
              proxy_set_header  X-Forwarded-Port  443;
      

      树枝

      <script src="{{ asset('build/common.js') }}"></script>
      

      将是&lt;script src="https://www.example.com/build/common.js"&gt;&lt;/script&gt;

      【讨论】:

        猜你喜欢
        • 2017-01-10
        • 1970-01-01
        • 2020-04-16
        • 1970-01-01
        • 2012-11-13
        • 2017-12-25
        • 1970-01-01
        • 1970-01-01
        • 2015-02-14
        相关资源
        最近更新 更多