【问题标题】:Cannot get TrustProxies middleware to work无法让 TrustProxies 中间件工作
【发布时间】:2017-11-10 23:28:08
【问题描述】:

在这里指出正确的方向后Laravel 5.4 relative instead of absolute 302 redirects
我一直在尝试让 Laravel TrustProxies 中间件工作,但似乎忽略了 X_FORWARDED_PROTO 标头。

我的场景
我在 Laravel 中的应用(刚刚从 5.4 升级到 5.5)位于负载均衡器后面,它将所有流量从 HTTPS 转换为 HTTP。

我的问题
所有重定向都通过 HTTP 而不是原始协议 HTTPS。

尝试的解决方案
从 Laravel 5.4 升级到 5.5 并利用现在随 Laravel 一起提供的 TrustProxies 中间件。
中间件有:

protected $proxies = '*';

/**
 * The current proxy header mappings.
 *
 * @var array
 */
protected $headers = [
    Request::HEADER_FORWARDED => 'FORWARDED',
    Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR',
    Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST',
    Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT',
    Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO',
];

App\Http\Kernel 已注册中间件:

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
    \App\Http\Middleware\TrimStrings::class,
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    \App\Http\Middleware\TrustProxies::class,
];

我的发现:
来自服务器的 Tcp 转储显示标头:

请求:

GET / HTTP/1.1
X_FORWARDED_PROTO: HTTPS
Host: mywebsiteaddress.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1

但响应具有通过 HTTP 的位置:

HTTP/1.1 302 Found
Date: Wed, 08 Nov 2017 18:03:48 GMT
Server: Apache/2.4.18 (Ubuntu)
Cache-Control: no-cache, private
Location: http://mywebsiteaddress.com/home
Set-Cookie: laravel_session=eyJp...In0%3D; expires=Wed, 08-Nov-2017 20:03:48 GMT; Max-Age=7200; path=/; HttpOnly
Content-Length: 376
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

其他 cmets:
由于我的应用程序从 5.4 升级到 5.5,我复制了在 5.5 全新安装中本来会存在的类 TrustProxies。然后我在内核中注册了它。
也许我在这里错过了一步。

我的希望:
我的疲倦并没有使我的头脑蒙上阴影,我忽略了一个简单的错误。

任何建议,提前谢谢!

更新:
在 Apache 中启用 log_forensics 模块,我在请求中看到 x-forwarded-proto 标头。

GET / HTTP/1.1
X_FORWARDED_PROTO:HTTPS
Host:mywebsiteaddress.com
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv%3a56.0) Gecko/20100101 Firefox/56.0
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language:en-US,en;q=0.5
Accept-Encoding:gzip, deflate, br
Connection:keep-alive
Upgrade-Insecure-Requests:1
Cache-Control:max-age=0

任何线索为什么 Laravel 可能没有 headers 数组?

【问题讨论】:

  • 顺便说一句,我做了一个 dd($_SERVER);在重定向之前的 routes/web.php 中,无法在标题中找到 X_FORWARED_PROTO。
  • 在您使用 5.4 时它是否有效?
  • @Suraj 我没有在 5.4 上进行测试,因为它代表了更多的手动配置,这意味着犯错的风险更大。我选择更好地升级到 5.5,因为它的成功概率更高。我即将在一个新的 5.5 模拟应用程序中进行测试,但需要与我的网络团队合作来复制该场景
  • 您在使用 AWS 负载均衡器吗?
  • 不@Suraj,这是我们自己的硬件负载平衡器。现在只是用于使用通配符 ssl 证书将我们的应用程序公开到互联网。此负载均衡器后面的所有应用程序都在侦听 HTTP。但我只对 Laravel 应用程序有这个问题。

标签: laravel load-balancing laravel-5.5 laravel-middleware


【解决方案1】:

确实很累。
负载平衡器一直在使用 C# (IIS) 应用程序的 X_FORWARDED_PROTO 标头,因此网络团队这次以相同的方式设置标头。
但是对于 Laravel,标题必须采用 X-FORWARDED-PROTO 的形式,我理解它是正确的名称(破折号而不是下划线)。
这就是为什么 Laravel(实际上是 Symfony)从请求中丢弃标头的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多