【问题标题】:symfony 4: Request.getScheme() return http with X_FORWARDED_PROTO httpssymfony 4:Request.getScheme() 返回带有 X_FORWARDED_PROTO https 的 http
【发布时间】:2018-06-21 08:47:52
【问题描述】:

来自$_SERVER php 数组:

$_SERVER['APP_ENV']                 prod
$_SERVER['APP_DEBUG']               0
$_SERVER['TRUSTED_PROXIES']         172.16.0.0/12
$_SERVER['HTTP_X_FORWARDED_FOR']    XXX.XXX.XXX.XXX
$_SERVER['HTTP_X_FORWARDED_HOST']   my.website.com
$_SERVER['HTTP_X_FORWARDED_PORT']   443
$_SERVER['HTTP_X_FORWARDED_PROTO']  https

来自 HTTP 标头:

X-Forwarded-For     XXX.XXX.XXX.XXX
X-Forwarded-Host    my.website.com
X-Forwarded-Port    443
X-Forwarded-Proto   https

在src/public/index.php

if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? false) {
    Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
}

在/src/Controller/TestController.php

class TestController 
{
    public function index(Request $request)
    {
        $response = new Response();
        $response->setContent(  $request->getScheme() );
        return $response;
    }
}

输出

http

但预期的输出是

https

为什么 symfony 返回错误的 http 方案?

【问题讨论】:

    标签: php symfony proxy symfony4 traefik


    【解决方案1】:

    在 Symfony 5 及更高版本中,您可以使用 config/packages/framework.yaml 中的这些设置告诉框架信任反向代理:

    framework:
    
        # the IP address (or range) of your proxy
        trusted_proxies: '192.0.0.1,10.0.0.0/8'
    
        # trust *all* "X-Forwarded-*" headers
        trusted_headers: ['x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port']
    

    这将在创建 url 或使用 $request->getScheme() 时产生正确的 https 协议。

    在Symfony documentation 中了解更多信息。

    【讨论】:

      【解决方案2】:

      你在使用抽象类AbstractController时有同样的输出吗?

      点赞class TestController extends AbstractController

      【讨论】:

        【解决方案3】:

        问题来自于 Traefik 返回的错误头名 HTTP_X_FORWARDED_PROTO

        Symfony 识别 FORWARDED 或 X_FORWARDED_PROTO

        Source (for symfony 3.4 (deprecated code removed in 4.x)

        protected static $trustedHeaders = array(
            self::HEADER_FORWARDED => 'FORWARDED',
            self::HEADER_CLIENT_IP => 'X_FORWARDED_FOR',
            self::HEADER_CLIENT_HOST => 'X_FORWARDED_HOST',
            self::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO',
            self::HEADER_CLIENT_PORT => 'X_FORWARDED_PORT',
        );
        

        根据this documentation,您必须像这样在 public/index.php 文件中设置正确的可信代理(启用 AWS ELB,它可以识别HTTP_X_FORWARDED_PROTO

        ...
        $kernel = new Kernel($env, $debug);
        $request = Request::createFromGlobals();
        
        // tell Symfony about your reverse proxy
        
        Request::setTrustedProxies(
        // the IP address (or range) of your proxy
        ['192.0.0.1', '10.0.0.0/8'],
        
        // trust *all* "X-Forwarded-*" headers
        // Request::HEADER_X_FORWARDED_ALL
        
        // or, if your proxy instead uses the "Forwarded" header
        // Request::HEADER_FORWARDED
        
        // or, if you're using AWS ELB
        Request::HEADER_X_FORWARDED_AWS_ELB
        );
        ...
        

        【讨论】:

          猜你喜欢
          • 2016-01-20
          • 1970-01-01
          • 1970-01-01
          • 2019-01-09
          • 2020-08-10
          • 1970-01-01
          • 2018-10-31
          • 1970-01-01
          • 2020-02-21
          相关资源
          最近更新 更多