Laravel 反向代理后面的路由
Laravel routes behind reverse proxy
好的,为了开发目的,我们有一个专用的网络服务器。它目前没有直接连接到互联网,所以我在另一台服务器上设置了一个 apache 反向代理,它转发到开发服务器。
这样,我就可以通过网络访问服务器了。
问题是,Laravel 中的路由现在以内部服务器 IP 地址或服务器计算机名称为前缀。
例如,我去 http://subdomain.test.com,但是使用 route()
助手生成的所有路线都显示以下内容 url: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
中设置了实际域名。
问题
如何设置默认 URL 以在路由中使用?我不希望它使用内部地址,因为这违背了反向代理的要点。
我试过将我所有的路线包含在一个 Route::group(['domain' ...
组中,这也不起作用。
好的,我明白了。希望这对以后的人有所帮助。
似乎 Laravel 忽略了 config\app.php
文件中的 url
属性 用于 http 请求(它确实声明它仅用于 artisan),而是使用 apache 提供的 HTTP_HOST
或 SERVER_NAME
为 URLs.
生成域
要覆盖此默认值 url,请转到您的 routes.php
文件并使用以下方法:
URL::forceRootUrl('http://subdomain.newurl.com');
这将强制 URL 生成器使用新的 url 而不是 HTTP_HOST 或 SERVER_NAME 值。
我 运行 遇到相同(或类似的问题),当时 Laravel 5 应用程序不知道处于 SSL load-balancer 之后。
我有以下设计:
- 客户端通过 HTTPS 与 SSL 负载平衡器对话
- SSL 负载平衡器通过 HTTP
与 back-end 服务器通信
但是,这会导致 HTML 代码中的所有 URL 都使用 http:// 架构生成。
以下是使这项工作正常进行的快速变通方法,包括架构(http 与 https):
将以下代码放在app/Http/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);
}
然后将以下行添加到 .env 文件中:
PROXY_URL = http://igateway.somedomain.com
如果您还需要将生成的 HTML 代码中的架构从 http:// 更改为 https://,只需添加以下行:
PROXY_SCHEMA = https
在 laravel 的最新版本中 forceSchema
方法名称已更改为 forceScheme
,上面的代码应如下所示:
if (!empty($proxy_schema)) {
URL::forceScheme($proxy_schema);
}
似乎 Laravel 有更方便的解决方案。检查那里的答案:
跟进@TimeLord的解决方案:
在最新版本的 laravel 中,强制模式的名称已更改,现在是:
URL::forceScheme()
我知道这个话题很旧 a.f 但我一直在通过替换 DatabaseSessionHandler.pdf [@Illuminate/Session]:
中的以下行来解决这个问题
protected function ipAddress()
{
return $_SERVER['HTTP_X_FORWARDED_FOR'];
// return $this->container->make('request')->ip();
}
当然你需要先迁移会话table并设置配置
(.env变量SESSION_DRIVER=数据库)
转到 app/Http/Middleware/TrustProxies.php 并像这样更改受保护变量 $proxies:
protected $proxies = ['127.0.0.1'];
就是这个!开心就好!
在 App\Providers\AppServiceProvider class
中添加此代码
if (Str::contains(Config::get('app.url'), 'https://')) {
URL::forceScheme('https');
}
对于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;
}
}
因为 laravel 路由不是从 config/app
本身而不是从服务器创建的。我的解决方案是将 proxy_set_header 主机添加到 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 中使用 laravel 8 和 nginx docker,所以是的,它是双 nginx
想出了一个更简洁的方法,并且只做负载均衡器告诉它的事情,将这个函数添加到你的 RouteServiceProvider
protected function enforceProtocol()
{
if(request()->server->has('HTTP_X_FORWARDED_PROTO')){
URL::forceScheme(request()->server()['HTTP_X_FORWARDED_PROTO']);
}
}
在引导部分,简单地这样调用它
public function boot()
{
$this->enforceProtocol();
//other stuff
}
好的,为了开发目的,我们有一个专用的网络服务器。它目前没有直接连接到互联网,所以我在另一台服务器上设置了一个 apache 反向代理,它转发到开发服务器。
这样,我就可以通过网络访问服务器了。
问题是,Laravel 中的路由现在以内部服务器 IP 地址或服务器计算机名称为前缀。
例如,我去 http://subdomain.test.com,但是使用 route()
助手生成的所有路线都显示以下内容 url: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
中设置了实际域名。
问题
如何设置默认 URL 以在路由中使用?我不希望它使用内部地址,因为这违背了反向代理的要点。
我试过将我所有的路线包含在一个 Route::group(['domain' ...
组中,这也不起作用。
好的,我明白了。希望这对以后的人有所帮助。
似乎 Laravel 忽略了 config\app.php
文件中的 url
属性 用于 http 请求(它确实声明它仅用于 artisan),而是使用 apache 提供的 HTTP_HOST
或 SERVER_NAME
为 URLs.
要覆盖此默认值 url,请转到您的 routes.php
文件并使用以下方法:
URL::forceRootUrl('http://subdomain.newurl.com');
这将强制 URL 生成器使用新的 url 而不是 HTTP_HOST 或 SERVER_NAME 值。
我 运行 遇到相同(或类似的问题),当时 Laravel 5 应用程序不知道处于 SSL load-balancer 之后。
我有以下设计:
- 客户端通过 HTTPS 与 SSL 负载平衡器对话
- SSL 负载平衡器通过 HTTP 与 back-end 服务器通信
但是,这会导致 HTML 代码中的所有 URL 都使用 http:// 架构生成。
以下是使这项工作正常进行的快速变通方法,包括架构(http 与 https):
将以下代码放在app/Http/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);
}
然后将以下行添加到 .env 文件中:
PROXY_URL = http://igateway.somedomain.com
如果您还需要将生成的 HTML 代码中的架构从 http:// 更改为 https://,只需添加以下行:
PROXY_SCHEMA = https
在 laravel 的最新版本中 forceSchema
方法名称已更改为 forceScheme
,上面的代码应如下所示:
if (!empty($proxy_schema)) {
URL::forceScheme($proxy_schema);
}
似乎 Laravel 有更方便的解决方案。检查那里的答案:
跟进@TimeLord的解决方案:
在最新版本的 laravel 中,强制模式的名称已更改,现在是:
URL::forceScheme()
我知道这个话题很旧 a.f 但我一直在通过替换 DatabaseSessionHandler.pdf [@Illuminate/Session]:
中的以下行来解决这个问题 protected function ipAddress()
{
return $_SERVER['HTTP_X_FORWARDED_FOR'];
// return $this->container->make('request')->ip();
}
当然你需要先迁移会话table并设置配置
(.env变量SESSION_DRIVER=数据库)
转到 app/Http/Middleware/TrustProxies.php 并像这样更改受保护变量 $proxies:
protected $proxies = ['127.0.0.1'];
就是这个!开心就好!
在 App\Providers\AppServiceProvider class
中添加此代码if (Str::contains(Config::get('app.url'), 'https://')) {
URL::forceScheme('https');
}
对于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;
}
}
因为 laravel 路由不是从 config/app
本身而不是从服务器创建的。我的解决方案是将 proxy_set_header 主机添加到 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 中使用 laravel 8 和 nginx docker,所以是的,它是双 nginx
想出了一个更简洁的方法,并且只做负载均衡器告诉它的事情,将这个函数添加到你的 RouteServiceProvider
protected function enforceProtocol()
{
if(request()->server->has('HTTP_X_FORWARDED_PROTO')){
URL::forceScheme(request()->server()['HTTP_X_FORWARDED_PROTO']);
}
}
在引导部分,简单地这样调用它
public function boot()
{
$this->enforceProtocol();
//other stuff
}