【问题标题】:Laravel routes behind reverse proxy反向代理后面的 Laravel 路由
【发布时间】:2015-07-06 22:11:33
【问题描述】:

好的,因此出于开发目的,我们有一个专用的 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 中设置了实际域名。

问题

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

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

【问题讨论】:

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


    【解决方案1】:

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

    我有以下设计:

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

    然而,这会导致 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);
    }
    

    【讨论】:

    • 它被称为scheme,而不是架构。
    • 这个答案需要更新。 app/Http/routes.php 不再存在
    【解决方案2】:

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

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

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

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

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

    【讨论】:

    • 谢谢你。我到处找。
    【解决方案3】:

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

    protected $proxies = ['127.0.0.1'];
    

    就这个!开心点!

    【讨论】:

    【解决方案4】:

    将此代码添加到 App\Providers\AppServiceProvider 类中

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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

          跟进@TimeLord 的解决方案:

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

          【讨论】:

            【解决方案8】:

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

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

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

            【讨论】:

              【解决方案9】:

              对于 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;
                  }
              }
              

              【讨论】:

                猜你喜欢
                • 2019-08-11
                • 1970-01-01
                • 1970-01-01
                • 2018-06-14
                • 2019-11-26
                • 2021-03-12
                • 2022-07-02
                • 2010-11-09
                • 1970-01-01
                相关资源
                最近更新 更多