Laravel 5.6 可信代理错误

29

今天我将 Laravel 升级到了 L5.6(更新了 Symfony 组件到 v4)。另外,根据官方 Laravel 5.6 升级指南,我也将 fideloper/proxy 包更新到了 4.0。

之后我开始遇到这个错误:Type error: Argument 2 passed to Symfony\Component\HttpFoundation\Request::setTrustedProxies() must be of the type integer, array given, called in /var/www/html/vendor/fideloper/proxy/src/TrustProxies.php on line 54

Symfony 4 的 Symfony\Component\HttpFoundation\Request::setTrustedProxies() 确实期望第二个参数为整数(位掩码):

/**
* Sets a list of trusted proxies.
*
* You should only list the reverse proxies that you manage directly.
*
* @param array $proxies          A list of trusted proxies
* @param int   $trustedHeaderSet A bit field of Request::HEADER_*, to set which headers to trust from your proxies
*
* @throws \InvalidArgumentException When $trustedHeaderSet is invalid
*/
public static function setTrustedProxies(array $proxies, int $trustedHeaderSet)
{
    self::$trustedProxies = $proxies;
    self::$trustedHeaderSet = $trustedHeaderSet;
}

而且fideloper/proxy 4.0确实会将一个数组传递给这个函数,而不是一个整数:

public function handle(Request $request, Closure $next)
{
    $request::setTrustedProxies([], $this->getTrustedHeaderNames()); // Reset trusted proxies between requests
    $this->setTrustedProxyIpAddresses($request);
    return $next($request);
}

/**
 * Retrieve trusted header name(s), falling back to defaults if config not set.
 *
 * @return array
 */
protected function getTrustedHeaderNames()
{
    return $this->headers ?: $this->config->get('trustedproxy.headers');
}

所以我不知道这是fideloper/proxy的bug还是我漏掉了什么?


一样的问题。项目从Laravel 5.5升级到5.6,运行vagrant homestead。尝试删除vendor目录并再次运行composer install-仍然存在同样的问题。请发布任何解决方案。 - Inigo
愚蠢的事情是:它在升级指南中提到了,但是在最后面。我滚动浏览它,期望最重要的更改首先出现,但是没有,实际上会破坏您的Web界面的更改在最后面 :) - Blizz
做了同样的事情 :) - SkifAlef
5个回答

33

经过一些调查(使用Winmerge比较全新安装的Laravel 5.6),发现问题在于文件 app\Http\Middleware\TrustProxies.php 的不同:

Laravel 5.5:

namespace App\Http\Middleware;

use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array
     */
    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',
    ];
}

Laravel 5.6:

namespace App\Http\Middleware;

use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array
     */
    protected $proxies;

    /**
     * The headers that should be used to detect proxies.
     *
     * @var string
     */
    protected $headers = Request::HEADER_X_FORWARDED_ALL;
}

因此,请根据Laravel 5.6版本设置protected $headers = Request::HEADER_X_FORWARDED_ALL;


请精确修复我的问题。 - Noni

23

打开app\Http\Middleware\TrustProxies.php文件。

更改如下内容

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',
];

protected $headers = Request::HEADER_X_FORWARDED_ALL;

从 Laravel 5.6 开始有用,我使用的是 Laravel 5.8,也很有帮助。祝你好运,2021 年新年快乐! - Osify

13
升级指南中所述,您需要将App\Http\Middleware\TrustProxies中的$ headers属性设置为位属性。
这些常量在Symfony\Component\HttpFoundation\Request中定义。
const HEADER_FORWARDED = 0b00001; // When using RFC 7239
const HEADER_X_FORWARDED_FOR = 0b00010;
const HEADER_X_FORWARDED_HOST = 0b00100;
const HEADER_X_FORWARDED_PROTO = 0b01000;
const HEADER_X_FORWARDED_PORT = 0b10000;
const HEADER_X_FORWARDED_ALL = 0b11110; // All "X-Forwarded-*" headers
const HEADER_X_FORWARDED_AWS_ELB = 0b11010; // AWS ELB doesn't send X-Forwarded-Host

在升级指南中,使用了HEADER_X_FORWARDED_ALL,但您可以使用位值的组合。

2
请注意,当从 Laravel 5.5 升级到 5.6 时,Laravel 会创建一个名为 TrustProxies.php 的新文件,与 TrustedProxies 具有相同的命名空间,即"App\Http\Middleware\TrustProxies"。在 Laravel 5.6 中,如上所述,TrustedProxies.php 文件是正确的。 而 TrustProxies.php 不是。但如果它们都存在于相同的命名空间中,那么 Laravel 将使用它首先找到的那个文件,即 TrustProxies.php 文件。
如果两者都存在,则删除 TrustProxies.php,并确保 TrustedProxies.php 具有如上所述的正确更改。
祝你拥有美好的一天。 Christian

0

如果您在Laravel 9.x或更高版本中遇到此问题,那是因为Laravel已经将该包合并到核心框架中,因此不再需要安装。

fideloper/TrustedProxy存储库已经在其自述文件中添加了一条说明,指示不要在Laravel 9.x上安装该包,而应按照Laravel升级指南进行操作。

您可以在Laravel文档这里找到升级说明,在“受信任的代理”标题下。

我发现在升级指南中的更改只花了我30秒钟就完成了!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接