反向代理背后的 Laravel 路由

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29912997/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 11:27:42  来源:igfitidea点击:

Laravel routes behind reverse proxy

apachelaravelroutinglaravel-5reverse-proxy

提问by Phil Cross

Ok, so for development purposes, we have a dedicated web server. It's not currently connected directly to the internet, so I've setup an apache reverse proxy on another server, which forwards to the development server.

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

This way, I can get web access to the server.

这样,我就可以通过网络访问服务器。

The problem is, the routes in Laravel are now being prefixed with the internal server IP address, or the servers computer name.

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

For example, I go to http://subdomain.test.combut all the routes, generated using the route()helper, are displaying the following url: http://10.47.32.22and not http://subdomain.test.com.

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

The reverse proxy is setup as such:

反向代理设置如下:

<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>

I have set the actual domain name in config\app.php.

我已经在config\app.php.

Question

How can I set the default URL to use in routing? I don't want it using the internal addresses, because that defeats the point of the reverse proxy.

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

I've tried enclosing all my routes in a Route::group(['domain' ...group, which doesn't work either.

我试过将我的所有路线都包含在一个Route::group(['domain' ...组中,这也不起作用。

回答by TimeLord

I ran into the same (or similar problem), when a Laravel 5 application was not aware of being behind an SSL load-balancer.

当 Laravel 5 应用程序不知道位于 SSL 负载平衡器之后时,我遇到了相同(或类似问题)。

I have the following design:

我有以下设计:

  • client talks to an SSL load balancer over HTTPS
  • SSL load balancer talks to a back-end server over HTTP
  • 客户端通过 HTTPS 与 SSL 负载平衡器对话
  • SSL 负载平衡器通过 HTTP 与后端服务器通信

That, however, causes all the URLs in the HTML code to be generated with http:// schema.

但是,这会导致 HTML 代码中的所有 URL 都使用 http:// 模式生成。

The following is a quick'n'dirty workaround to make this work, including the schema (http vs. https):

以下是使此工作正常进行的快速解决方法,包括架构(http 与 https):

Place the following code on top of app/Http/routes.php

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

In latest version of laravel, use web/routes.php

在最新版本的 Laravel 中,使用web/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);
}

then add the following line into .envfile:

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

PROXY_URL = http://igateway.somedomain.com

If you also need to change schema in the generated HTML code from http://to https://, just add the following line as well:

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

PROXY_SCHEMA = https

In latest version of laravel forceSchemamethod name has changed to forceSchemeand the code above should look like this:

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

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

回答by Phil Cross

Ok, so I got it. Hopefully this will help someone in the future.

好的,所以我明白了。希望这会在将来对某人有所帮助。

It seems like Laravel ignores the urlproperty in the config\app.phpfile for http requests (it does state it's only for artisan), and it instead uses either HTTP_HOSTor SERVER_NAMEprovided by apache to generate the domain for URLs.

似乎 Laravel 忽略了http 请求文件中的url属性config\app.php(它确实声明它仅适用于工匠),而是使用apache 提供的HTTP_HOSTSERVER_NAME来生成 URL 的域。

To override this default url, go to your routes.phpfile and use the following method:

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

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

This will then force the URL generator to use the new url instead of the HTTP_HOST or SERVER_NAME value.

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

回答by Alex

Seems the Laravel have more convinient solution.. Check answer there: How do I configure SSL with Laravel 5 behind a load balancer (ssl_termination)?

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

回答by Giorgi Ghughunishvili

Following up @TimeLord's solution:

跟进@TimeLord 的解决方案:

In latest version of laravel the name for forced schema has changed and now it is: URL::forceScheme()

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

回答by Fabus

I know this topic is old a.f but I've been solving this issue by replacing the following line in my DatabaseSessionHandler.pdf [@Illuminate/Session]:

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

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

Of course you need to migrate the sesssion table first and set up the config
(.env Variable SESSION_DRIVER=database)

当然你需要先迁移会话表并设置配置
(.env Variable SESSION_DRIVER=database)