如何让Symfony 2采用协议方案(http vs https)

时间:2015-02-05 20:57:45

标签: php http symfony https

我有一个Symfony 2网站,可以在开发中的HTTP上运行,也可以在生产中的HTTPS上运行。

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

我怎么能;

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

6 个答案:

答案 0 :(得分:11)

@ A.L和@AndreySobkanyuk给出的解决方案均有效,但不适用于我遇到的问题。

@ A.L和@AndreySobkanyuk提供的两种解决方案的问题在于Symfony 2正在尝试重定向。即如果通过协议(例如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点击了网址。
  2. 负载均衡器将请求作为HTTP传递给Web服务器。
  3. 在Symfony中,路由配置为使用HTTPS,从而导致PHP级别的重定向。
  4. 回到1(无限循环)。
  5. 要解决我的问题,我必须让我的网络服务器知道我的网站在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')));
    

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

答案 1 :(得分:6)

我发现这对我的情况很有用(使用 nginx

添加到nginx fcgi params以下行,这是必需的,因为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/

答案 2 :(得分:5)

要在生产环境中强制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中,您可以放置​​所有路线。

  4. 有关schemes: [https]及其他方法的更多信息,请查看Symfony documentation

答案 3 :(得分:1)

我使用此解决方案强制使用HTTP或HTTPS:

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

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

parameters:
    auth_required_channel: 'http'

应用程序/配置/ config_prod.yml

parameters:
    auth_required_channel: 'https'

应用程序/配置/ security.yml

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

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

(改编自old answer

答案 4 :(得分:1)

假设这种情况:

  • 您的Symfony应用程序支持反向代理,如Varnish或BigIP
  • 您希望将原始客户端IP用作REMOTE_ADDR(即mod_rpaf扩展名为trusted_proxies(当然,在这种情况下,您无法使用SetEnvIf x-forwarded-proto https HTTPS=on 值)

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

在Apache中:

{{1}}

答案 5 :(得分:0)

如果您要在https方案中的反向代理/负载均衡器后面和https呈现url /资产后面进行挖掘,请务必转发方案端口

例如反向代理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>

将是<script src="https://www.example.com/build/common.js"></script>