PHP群:95885625 Hbuilder+MUI群:81989597 站长QQ:634381967
    您现在的位置: 首页 > 开发编程 > Laravel教程 > 正文

    laravel + haproxy + https 后生成分页 url 非 https 解决办法

    作者:admin来源:网络浏览:时间:2018-04-14 18:48:15我要评论
    分享到
    导读:更合适的解决办法:在AppServiceProviderboot方法中使用\URL::forceScheme('https');即可。背景近日对所有的客户都上线了 https ...
    更合适的解决办法:在 AppServiceProvider boot 方法中使用 \URL::forceScheme('https'); 即可。

    背景

    近日对所有的客户都上线了 https ,本来在 beta 环境中是没有任何问题,都测试通过了,但是在正式上线后,发现后台管理系统中的 laravel 分页生成的 url 是非 https 的,但是其他地方(路由,静态资源)等生成的都是正常的 https 链接,遂找原因解决。

    解决

    laravel 的分页服务 Illuminate\Pagination\PaginationServiceProvider::class 找到该 ServiceProvider 源码中 register() 中的代码

    Paginator::currentPathResolver(function () {
            return $this->app['request']->url();
    });

    可以看到分页链接生成的时候,是根据当前请求的 url 来设置分页类的 url path.

    接着找到 Illuminate\Http\Request::class 中的 url()

        public function url()
        {
            return rtrim(preg_replace('/\?.*/', '', $this->getUri()), '/');
        }

    在这里我们可以发现 laravel 的 Request 类是继承自 Symfony 的 Request,通过不断地位我们可以找到如下代码:

        public function isSecure()
        {
            if ($this->isFromTrustedProxy() && self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && $proto = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO])) {
                return in_array(strtolower(current(explode(',', $proto))), array('https', 'on', 'ssl', '1'));
            }
    
            $https = $this->server->get('HTTPS');
    
            return !empty($https) && 'off' !== strtolower($https);
        }

    看到这段源码后,我们打印了生产环境中的 phpinfo

    laravel + haproxy + https 后生成分页 url 非 https 解决办法

    通过源码对比发现,Symfony 中默认读取的是 X_FORWARDED_PROTO and X_FORWARDED_PORT,但是我们 php 环境中是 HTTP_X_FORWARDED_PROTO and HTTP_X_FORWARDED_PORT,我们在源码中发现了如下方法:

        /**
         * Sets the name for trusted headers.
         *
         * The following header keys are supported:
         *
         *  * Request::HEADER_CLIENT_IP:    defaults to X-Forwarded-For   (see getClientIp())
         *  * Request::HEADER_CLIENT_HOST:  defaults to X-Forwarded-Host  (see getHost())
         *  * Request::HEADER_CLIENT_PORT:  defaults to X-Forwarded-Port  (see getPort())
         *  * Request::HEADER_CLIENT_PROTO: defaults to X-Forwarded-Proto (see getScheme() and isSecure())
         *
         * Setting an empty value allows to disable the trusted header for the given key.
         *
         * @param string $key   The header key
         * @param string $value The header name
         *
         * @throws \InvalidArgumentException
         */
        public static function setTrustedHeaderName($key, $value)
        {
            if (!array_key_exists($key, self::$trustedHeaders)) {
                throw new \InvalidArgumentException(sprintf('Unable to set the trusted header name for key "%s".', $key));
            }
    
            self::$trustedHeaders[$key] = $value;
        }

    可以发现这是一个静态方法,因此我们只需要在 AppServiceProvider 中加入如下代码即可

     
    Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT,'HTTP_X_FORWARDED_PORT');
    Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO,'HTTP_X_FORWARDED_PROTO');
    转载请注明(B5教程网)原文链接:http://www.bcty365.com/content-153-6264-1.html
    相关热词搜索:
    网友评论: