Laravel 当应用程序通过 GuzzleHttp 相互调用时,环境变量在应用程序之间泄漏

Laravel environment variables leaking between applications when they call each other through GuzzleHttp

我的本地计算机上有两个 Laravel 5.2 应用程序(我们称它们为 A 和 B),它们都配置在我本地 Apache 2.4 开发服务器上的两个不同的虚拟主机上。

这两个应用程序有时会通过 GuzzleHttp 相互调用。

有一次我想使用加密,我开始从 Laravel 的加密器中获得 "mac is invalid" 异常。

在调查这个问题时,我发现当应用程序A调用应用程序B时,应用程序B突然从应用程序A获取加密密钥(app.key)!这会导致加密中断,因为应用程序 B 上的值是使用应用程序 B 的加密密钥加密的。

调试时,我发现 Dotenv 库有一些逻辑可以保留现有变量(如果已设置)。我发现 $_ENV 和 $_SERVER 都没有泄漏变量,但是 getenv() 有!

我有点困惑,因为 PHP putenv 说:

The environment variable will only exist for the duration of the current request.

似乎,如果在当前请求期间我通过 GuzzleHttp 启动另一个请求,Dotenv 在 A 中使用 putenv() 设置的变量突然在 GuzzleHttp 请求的应用程序 B 中可用!

我知道这在将使用配置缓存而不是 Dotenv 的生产服务器上不会成为问题,并且很可能这两个应用程序将 运行 在不同的 Apache 服务器上运行,但这种行为正在破坏我的开发过程.

如何配置 Laravel 或 GuzzleHttp 或 Apache 或 PHP 以防止此 putenv() 从应用程序 A 泄漏到应用程序 B?

问题是您正在使用 PHP 的共享实例,因此当其中一个应用程序设置与另一个应用程序共享的环境变量时。我相信 phpdotenv 将它们视为不可变的,因此一旦它们被设置,其他应用程序就无法覆盖它们。

mod_php(我假设你在使用,因为你提到了 apache)基本上在每个 apache 进程中提供了一个 php 解释器。 apache 进程将在您所有的虚拟主机之间共享,因此您会遇到此问题。如果你是 运行 nginx 和 php-fpm,你也会遇到同样的问题,但是如果你是 运行 后者的软件堆栈,它更容易解决。

很遗憾,一个端口只能绑定一个进程。因此,坚持使用 mod_php 和 apache 的唯一方法是将您的虚拟主机放在单独的端口号上,这意味着您必须在访问时将其中至少一个的端口号放在 url 中它。我真的不再使用 apache 所以我不能给你具体的细节,这可能只是在你的虚拟主机配置中设置不同的端口,apache 会这样做,但我不得不推迟你太 google.

如果你是 运行 nginx/php-fpm 可能只是在不同的端口或套接字上创建第二个 php-fpm 进程配置 运行 和将第二个虚拟主机指向那个 php 实例然后离开。

总而言之,您有几个解决方案:

  1. 继续使用 apache 和 mod_php,然后用这周剩下的时间用谷歌搜索如何按照我说的去做。
  2. 查看 运行 php,因为 apache 上的 cgi 模块将为您提供所需的灵活性(这类似于使用 nginx/php-fpm 但无需更改您的网络服务器软件) .
  3. 停止使用 phpdotenv 并寻找替代方法(例如在 htaccess 或 vhost 中加载您的配置,以便它可以作为 $_ENV 或 $_SERVER 键使用)
  4. 安装一个包含 nginx/php-fpm 的开发堆栈,它应该可以通过创建两个 php 进程轻松解决
  5. 使用虚拟机(可能看vagrant或者docker) .

抱歉,我没有更好的消息,但不幸的是,您的 WAMP 堆栈开箱即用的限制太多了。

我在 Windows 上与 (XAMPP) Apache vHosts 面临同样的问题。

肮脏的骇客;正在缓存您的配置...

php artisan config:cache

来源:#219

注意:您需要在 运行 phpunit 测试之前清除配置缓存。

php artisan config:clear

./vendor/bin/phpunit

php artisan config:cache