Laravel在反向代理

时间:2015-04-28 07:29:05

标签: apache laravel routing laravel-5 reverse-proxy

好的,为了开发目的,我们有一个专用的Web服务器。它目前没有直接连接到互联网,所以我在另一台服务器上设置了一个apache反向代理,然后转发到开发服务器。

这样,我就可以访问服务器了。

问题是,Laravel中的路由现在以内部服务器IP地址或服务器计算机名称为前缀。

例如,我转到http://subdomain.test.com,但使用route()帮助程序生成的所有路径都显示以下网址:http://10.47.32.22而不是http://subdomain.test.com

反向代理设置如下:

<VirtualHost *:80>
    ServerName igateway.somedomain.com

    ProxyRequests Off
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    ProxyPass / http://10.47.32.22:80/
    ProxyPassReverse / http://10.47.32.22:80/
    <Location />
        Order allow,deny
        Allow from all
    </Location>
</VirtualHost>

我已在config\app.php中设置了实际的域名。

问题

如何设置在路由中使用的默认网址?我不希望它使用内部地址,因为这违背了反向代理的要点。

我已尝试将我的所有路线封闭在Route::group(['domain' ...群组中,但这些路线也无效。

9 个答案:

答案 0 :(得分:15)

当Laravel 5应用程序不知道是在SSL负载均衡器后面时,我遇到了同样的问题(或类似的问题)。

我有以下设计:

  • 客户端通过HTTPS与SSL负载均衡器进行通信
  • SSL负载均衡器通过HTTP与后端服务器进行通信

然而,这会导致HTML代码中的所有URL都使用http:// schema。

生成

以下是一项快速的解决方法,可以帮助您完成这项工作,包括架构(http与https):

将以下代码放在 app / Http / routes.php

之上
$proxy_url    = getenv('PROXY_URL');
$proxy_schema = getenv('PROXY_SCHEMA');

if (!empty($proxy_url)) {
   URL::forceRootUrl($proxy_url);
}

if (!empty($proxy_schema)) {
   URL::forceSchema($proxy_schema);
}

然后将以下行添加到 .env 文件中:

PROXY_URL = http://igateway.somedomain.com

如果您还需要将生成的HTML代码中的架构从 http:// 更改为 https:// ,只需添加以下行:

PROXY_SCHEMA = https

在最新版本的laravel forceSchema中,方法名称已更改为forceScheme,上面的代码应如下所示:

if (!empty($proxy_schema)) {
    URL::forceScheme($proxy_schema);
}

答案 1 :(得分:5)

好的,所以我明白了。希望这将有助于未来的人。

似乎Laravel在url文件中忽略了http请求的config\app.php属性(它确实只为工匠说明了它),而是使用HTTP_HOST或者由apache提供的SERVER_NAME来生成URL的域名。

要覆盖此默认网址,请转到routes.php文件并使用以下方法:

URL::forceRootUrl('http://subdomain.newurl.com');

这将强制URL生成器使用新的url而不是HTTP_HOST或SERVER_NAME值。

答案 2 :(得分:3)

转到 app/Http/Middleware/TrustProxies.php 并像这样更改受保护的变量 $proxies:

protected $proxies = ['127.0.0.1'];

就这个!开心点!

答案 3 :(得分:2)

在 App\Providers\AppServiceProvider 类中添加这段代码

URL::forceRootUrl(Config::get('app.url'));
if (Str::contains(Config::get('app.url'), 'https://')) {
    URL::forceScheme('https');
}

答案 4 :(得分:0)

似乎Laravel有更方便的解决方案..检查那里的答案:How do I configure SSL with Laravel 5 behind a load balancer (ssl_termination)?

答案 5 :(得分:0)

跟进@TimeLord的解决方案:

在最新版本的laravel中,强制模式的名称已更改,现在为: URL::forceScheme()

答案 6 :(得分:0)

我知道这个话题很老,但是我一直通过替换DatabaseSessionHandler.pdf [@ Illuminate / Session]中的以下行来解决此问题:

    protected function ipAddress()
    {
        return $_SERVER['HTTP_X_FORWARDED_FOR'];
//        return $this->container->make('request')->ip();
    }

当然,您需要先迁移会话表并设置配置
(.env变量SESSION_DRIVER =数据库)

答案 7 :(得分:0)

对于 nginx,你不需要在 Laravel 中做任何额外的事情。修复可以从 nginx 配置完成;

server {
    listen 80;
    listen [::]:80 ipv6only=on;

    server_name sub.domain.dev;

    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host  sub.domain.dev;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:8000;
    }
}

答案 8 :(得分:0)

因为 laravel 路由不是从 config/app 本身创建的,而是从服务器创建的。我的解决方案是将 proxy_set_header Host 添加到 nginx 的配置中。

server {
    listen 80;
    server_name my.domain.com;

    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host  my.domain.com;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:8000;
    } 
}

我在机器上正在运行的 nginx 中使用带有 nginx docker 的 laravel 8,所以是的,它是双 nginx