web-dev-qa-db-ja.com

Laravel 5.6 TrustedProxiesエラー

今日、L5.5から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()は実際、2番目の引数として整数(ビットマスク)を期待しています:

_/**
* 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_のバグなのか、何かが足りないのか理解できませんか?

19
SkifAlef

アップグレードガイド に記載されているように、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が使用されますが、ビット値の組み合わせを使用できます。

11
WJDev

何らかの調査(Laravel 5.6の新規インストールとのWinmergeの比較)の後、ファイル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;
}

エルゴ、protected $headers = Request::HEADER_X_FORWARDED_ALL; as Laravel 5.6バージョン

23
Inigo

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

to

protected $headers = Request::HEADER_X_FORWARDED_ALL;
13
aphoe

Laravel 5.5から5.6にアップグレードするとき、Laravelは、TrustedProxiesと同じ名前空間(つまり"App\Http\Middleware\TrustProxies")でTrustProxies.phpという新しいファイルを作成することにも留意してください。 Laravel 5.6では、TrustedProxies.phpファイルは上記のように正しいです。
TrustProxies.phpはそうではありません。しかし、両方が同じ名前空間に存在する場合、Laravelは最初に見つけたものを使用します。これがTrustProxies.phpファイルです。

両方がある場合は、TrustProxies.phpを削除し、TrustedProxies.phpに上記の正しい変更があることを確認してください。

素晴らしい一日を過ごします。クリスチャン