laravel + haproxy + https 後生成分頁 url 非 https 解決辦法

更合適的解決辦法:在  AppServiceProvider boot 方法中使用  \URL::forceScheme('https'); 便可。

背景

近日對全部的客戶都上線了 https ,原本在 beta 環境中是沒有任何問題,都測試經過了,可是在正式上線後,發現後臺管理系統中的 laravel 分頁生成的 url 是非 https 的,可是其餘地方(路由,靜態資源)等生成的都是正常的 https 連接,遂找緣由解決。php

解決

laravel 的分頁服務 Illuminate\Pagination\PaginationServiceProvider::class 找到該 ServiceProvider 源碼中 register() 中的代碼laravel

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

能夠看到分頁連接生成的時候,是根據當前請求的 url 來設置分頁類的 url path.app

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

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); }

看到這段源碼後,咱們打印了生產環境中的 phpinfothis

經過源碼對比發現,Symfony 中默認讀取的是 X_FORWARDED_PROTO and X_FORWARDED_PORT,可是咱們 php 環境中是 HTTP_X_FORWARDED_PROTO and HTTP_X_FORWARDED_PORT,咱們在源碼中發現了以下方法:url

/** * 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 中加入以下代碼便可spa

 
Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT,'HTTP_X_FORWARDED_PORT'); Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO,'HTTP_X_FORWARDED_PROTO');
相關文章
相關標籤/搜索