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 实例然后离开。
总而言之,您有几个解决方案:
- 继续使用 apache 和 mod_php,然后用这周剩下的时间用谷歌搜索如何按照我说的去做。
- 查看 运行 php,因为 apache 上的 cgi 模块将为您提供所需的灵活性(这类似于使用 nginx/php-fpm 但无需更改您的网络服务器软件) .
- 停止使用 phpdotenv 并寻找替代方法(例如在 htaccess 或 vhost 中加载您的配置,以便它可以作为 $_ENV 或 $_SERVER 键使用)
- 安装一个包含 nginx/php-fpm 的开发堆栈,它应该可以通过创建两个 php 进程轻松解决
- 使用虚拟机(可能看vagrant或者docker)
.
抱歉,我没有更好的消息,但不幸的是,您的 WAMP 堆栈开箱即用的限制太多了。
我在 Windows 上与 (XAMPP) Apache vHosts 面临同样的问题。
肮脏的骇客;正在缓存您的配置...
php artisan config:cache
来源:#219
注意:您需要在 运行 phpunit 测试之前清除配置缓存。
php artisan config:clear
./vendor/bin/phpunit
php artisan config:cache
我的本地计算机上有两个 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 实例然后离开。
总而言之,您有几个解决方案:
- 继续使用 apache 和 mod_php,然后用这周剩下的时间用谷歌搜索如何按照我说的去做。
- 查看 运行 php,因为 apache 上的 cgi 模块将为您提供所需的灵活性(这类似于使用 nginx/php-fpm 但无需更改您的网络服务器软件) .
- 停止使用 phpdotenv 并寻找替代方法(例如在 htaccess 或 vhost 中加载您的配置,以便它可以作为 $_ENV 或 $_SERVER 键使用)
- 安装一个包含 nginx/php-fpm 的开发堆栈,它应该可以通过创建两个 php 进程轻松解决
- 使用虚拟机(可能看vagrant或者docker) .
抱歉,我没有更好的消息,但不幸的是,您的 WAMP 堆栈开箱即用的限制太多了。
我在 Windows 上与 (XAMPP) Apache vHosts 面临同样的问题。
肮脏的骇客;正在缓存您的配置...
php artisan config:cache
来源:#219
注意:您需要在 运行 phpunit 测试之前清除配置缓存。
php artisan config:clear
./vendor/bin/phpunit
php artisan config:cache