Laravel 5.4 相对而非绝对 302 重定向
Laravel 5.4 relative instead of absolute 302 redirects
我在使用负载平衡器后的新 Laravel 应用程序时遇到问题。
我想让 Laravel 将 Auth 中间件 302 重定向到相对路径,例如 /login 而不是 http://myappdomain.com/login其实是在做。
我在默认的 .htaccess Laravel 中只看到 301 重定向,这让我相信 Laravel 中的行为是正确的,我错了吗?
有人能给我指出正确的方向吗?
如果您需要正确确定负载均衡器后面的请求是否安全,您需要让框架知道您在代理后面。这将确保 route()
和 url()
助手生成正确的 URL 并消除创建相对重定向的需要,这两者都不是浏览器 100% 支持的,并且在从sub-path.
这就是我们用来解决这个问题的方法,到目前为止它对我们有效:
.env
LOAD_BALANCER_IP_MASK=aaa.bbb.ccc.ddd/xx #Subnet mask
负载均衡中间件
class LoadBalanced {
public function handle($request, $next) {
if (env("LOAD_BALANCER_IP_MASK")) {
$request->setTrustedProxies([ env("LOAD_BALANCER_IP_MASK") ]);
}
$next($request);
}
}
然后把中间件放在你的Kernel.php
:
protected $middleware = [
LoadBalanced::class,
//.... It shouldn't matter if it's first or last as long as other global middleware don't need it
];
这是 Laravel 可用的功能,因为它使用 Symfony 请求作为基础。负载均衡器转发一些重要的 header 是如何工作的。 Symfony 目前理解:
protected static $trustedHeaders = array(
self::HEADER_FORWARDED => 'FORWARDED',
self::HEADER_CLIENT_IP => 'X_FORWARDED_FOR',
self::HEADER_CLIENT_HOST => 'X_FORWARDED_HOST',
self::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO',
self::HEADER_CLIENT_PORT => 'X_FORWARDED_PORT',
);
其中包含有关向负载平衡器发出请求的用户和使用的协议的信息。
同样根据框架评论:
The FORWARDED header is the standard as of rfc7239.
The other headers are non-standard, but widely used
by popular reverse proxies (like Apache mod_proxy or Amazon EC2).
更新:
从 5.5 版开始,Laravel 样板包包含 TrustedProxy
middleware which uses the fideloper/TrustedProxy 包。
要使其正常工作,您需要 (a) 确保它位于 App\Http\Kernel
class 中的 $middleware
数组中,并且将受信任代理的 IP 放入此中间件例如
protected $proxies = [
'1.2.3.4'
];
我强烈建议明确指定您的代理发送哪些转发的 header,例如:
protected $headers = Request::HEADER_X_FORWARDED_AWS_ELB;
如果您使用的是 AWS 负载均衡器。
这样做的原因非常重要,因为如果您使用的是 AWS 负载均衡器,那么有人可以使用“转发”header 制作一个请求,该请求将由 AWS 转发,然后由中间件基本上允许用户欺骗他们的 IP host/port 等
我在使用负载平衡器后的新 Laravel 应用程序时遇到问题。 我想让 Laravel 将 Auth 中间件 302 重定向到相对路径,例如 /login 而不是 http://myappdomain.com/login其实是在做。
我在默认的 .htaccess Laravel 中只看到 301 重定向,这让我相信 Laravel 中的行为是正确的,我错了吗?
有人能给我指出正确的方向吗?
如果您需要正确确定负载均衡器后面的请求是否安全,您需要让框架知道您在代理后面。这将确保 route()
和 url()
助手生成正确的 URL 并消除创建相对重定向的需要,这两者都不是浏览器 100% 支持的,并且在从sub-path.
这就是我们用来解决这个问题的方法,到目前为止它对我们有效:
.env
LOAD_BALANCER_IP_MASK=aaa.bbb.ccc.ddd/xx #Subnet mask
负载均衡中间件
class LoadBalanced {
public function handle($request, $next) {
if (env("LOAD_BALANCER_IP_MASK")) {
$request->setTrustedProxies([ env("LOAD_BALANCER_IP_MASK") ]);
}
$next($request);
}
}
然后把中间件放在你的Kernel.php
:
protected $middleware = [
LoadBalanced::class,
//.... It shouldn't matter if it's first or last as long as other global middleware don't need it
];
这是 Laravel 可用的功能,因为它使用 Symfony 请求作为基础。负载均衡器转发一些重要的 header 是如何工作的。 Symfony 目前理解:
protected static $trustedHeaders = array(
self::HEADER_FORWARDED => 'FORWARDED',
self::HEADER_CLIENT_IP => 'X_FORWARDED_FOR',
self::HEADER_CLIENT_HOST => 'X_FORWARDED_HOST',
self::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO',
self::HEADER_CLIENT_PORT => 'X_FORWARDED_PORT',
);
其中包含有关向负载平衡器发出请求的用户和使用的协议的信息。
同样根据框架评论:
The FORWARDED header is the standard as of rfc7239.
The other headers are non-standard, but widely used by popular reverse proxies (like Apache mod_proxy or Amazon EC2).
更新:
从 5.5 版开始,Laravel 样板包包含 TrustedProxy
middleware which uses the fideloper/TrustedProxy 包。
要使其正常工作,您需要 (a) 确保它位于 App\Http\Kernel
class 中的 $middleware
数组中,并且将受信任代理的 IP 放入此中间件例如
protected $proxies = [
'1.2.3.4'
];
我强烈建议明确指定您的代理发送哪些转发的 header,例如:
protected $headers = Request::HEADER_X_FORWARDED_AWS_ELB;
如果您使用的是 AWS 负载均衡器。
这样做的原因非常重要,因为如果您使用的是 AWS 负载均衡器,那么有人可以使用“转发”header 制作一个请求,该请求将由 AWS 转发,然后由中间件基本上允许用户欺骗他们的 IP host/port 等