在 AWS Elastic Beanstalk 中部署后浏览 https 时,Laravel 资产、路由和 url() 不起作用

Posted

技术标签:

【中文标题】在 AWS Elastic Beanstalk 中部署后浏览 https 时,Laravel 资产、路由和 url() 不起作用【英文标题】:Laravel assets, routes and url() not working when browse https after deploy in AWS Elastic Beanstalk 【发布时间】:2021-10-28 00:59:16 【问题描述】:

我使用 AWS elastic beanstalk 来部署我的 laravel 项目。一切正常,但我的资产、路线和无法获得真实的用户 ip。

Assets:尽管我浏览 https,但在调用 assets() 时它引用了 http。从 https 读取 http 资产的站点块

路由:尽管我浏览 https,但始终指向 http

URL:尽管我浏览 https,但始终返回 http

IP:始终返回服务器 IP。永远不要获得真正的用户 IP。但它适用于其他服务器,但不适用于 AWS elastic beanstalk

我该怎么办?欢迎任何解决方案,我们将不胜感激。

【问题讨论】:

【参考方案1】:

使用 AWS 或任何其他云负载均衡器时的两个常见问题:

    HTTPS(Laravel 资产和路由):您应用了 SSL/TLS,并且 URL 在浏览器中受到保护,但 Laravel 不会加载您的资产并引发错误。由于您尝试加载 http URL http 请求,该错误看起来像是阻止了 URL。大多数人在使用AWS or any other cloud Load Balancer 时都会遇到这个问题。在终止 TLS / SSL 证书的负载均衡器后面运行应用程序时,您可能会注意到您的应用程序在使用 url 帮助程序时有时不会生成 HTTPS 链接。这通常是因为您的应用程序正在从端口 80 上的负载均衡器转发流量,并且不知道它应该生成安全链接。

    IP:另一个问题是IP问题。您无法获取用户/访问者 IP,它始终返回服务器 IP。这个问题也因为proxies而发生。

Solution:当您使用AWS or any cloud Load Balancer 时,您可能不知道实际Loads Balancer 的确切IP 地址,因此应允许所有代理,如下例所示。

使用* 允许信任您的TrustProxies 中间件中的所有代理。这是你的中间件app/Http/Middlewares/TrustProxies.php

namespace App\Http\Middleware;

use Fideloper\Proxy\TrustProxies as Middleware;
use Illuminate\Http\Request;

class TrustProxies extends Middleware

    /**
     * The trusted proxies for this application.
     *
     * @var string|array
     */
     protected $proxies = '*';

    /**
     * The headers that should be used to detect proxies.
     *
     * @var int
     */
    protected $headers = Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO;

如果您使用的是 AWS Elastic Load Balancing,则您的 $headers 值应为 Request::HEADER_X_FORWARDED_AWS_ELB. 有关 $headers 属性中可能使用的常量的更多信息,请查看 trusting proxies 上的 Symfony 文档。

namespace App\Http\Middleware;

use Fideloper\Proxy\TrustProxies as Middleware;
use Illuminate\Http\Request;

class TrustProxies extends Middleware

    /**
     * The trusted proxies for this application.
     *
     * @var array|string
     */
    protected $proxies = '*';

    /**
     * The headers that should be used to detect proxies.
     *
     * @var int
     */
    protected $headers = Request::HEADER_X_FORWARDED_AWS_ELB;

我认为它解决了您的 HTTPS、IP 和其他代理相关问题。要阅读更多详细信息,请阅读Laravel doc。

Solution 2 :还有另一种方法可以通过强制输入 AppServiceProvider 来允许 https 或创建一个新的中间件来实现这一点。在我的代码 sn-p 中,我决定使用AppServiceProvider,因为它易于实现。在任何文本编辑器中打开 app/Providers/AppServiceProvider.php 并写入 $this->app['request']->server->set('HTTPS', true);。您可以在生产模式下额外检查该APP。

if(request()->getRequestUri() != '/health' && $this->app->environment('production')) 
            $this->app['request']->server->set('HTTPS', true);
        

request()->getRequestUri() != '/health' 用于 AWS ALB 安全组的 health check,因为它不支持 https。

    您可以使用URL::forceScheme('https') 强制资产网址为https。

最后一个解决方案 2 和 3 仅适用于资产、https 和 url(),但不适用于真实 IP。所以我建议使用第一个解决方案,因为它适用于所有情况。如果您不想允许代理,那么解决方案 2 是最有效的。

如果您遇到任何其他问题或需要改进以下 cmets。

祝你好运。享受吧!

【讨论】:

以上是关于在 AWS Elastic Beanstalk 中部署后浏览 https 时,Laravel 资产、路由和 url() 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AWS elastic-beanstalk 中更改我的 python 版本

如何在 AWS Elastic Beanstalk 中更改数据库配置

在 AWS Elastic Beanstalk 和 EKS 上部署了一个 laravel 应用程序 相同的数据库 RDS 为啥在 Elastic Beanstalk 中获得快速响应

如何在 AWS Elastic Beanstalk 中选择特定平台?

在 AWS Elastic Beanstalk 中运行 composer 命令

AWS Elastic Beanstalk 中的 HTTPS 配置