PHP和MySQL – 如何避免源代码中的密码?

我有一个小的PHP应用程序存储在MySQL数据库中的数据。 目前用户名/密码是在PHP代码中硬编码的。 例如,我不太喜欢这种情况,因为代码也可以在存储库中使用。

我最好的想法是将数据从代码移动到configuration文件(从存储库中排除),并以某种方式对其进行编码,所以不能直接读取(混淆)。 有没有更好的和易于使用的方法来解决这个问题?

$link = mysql_connect('localhost', 'mysql_user', 'mysql_password'); if (!$link) { die('Could not connect: ' . mysql_error()); } mysql_select_db('mydb'); 

范围:我想build立一个强大的,但也易于使用的解决scheme。 我想要合理的安全性,但是我并没有在这里处理高度机密的数据。

备注:不再推荐使用mysql_connect函数,请参阅Stack Overflow问题为什么不应该在PHP中使用mysql_函数? *。 我可以改变代码示例,但由于一些评论指的是这个,我没有。 但是,问题的本质仍然是有效的。

最简单的方法就像你所说的那样,使用一个configuration文件。

许多框架使用这个( Zend , CakePHP , Kohana等),这是最常见的做法(即使在非PHP环境下,例如使用web.config文件的ASP.NET)。 这样,您也可以通过复制站点的文件来将configuration值从环境复制到环境,这比依赖服务器设置环境variables(可能会很快丢失和遗忘)更为有利。

你不需要担心密码混淆,因为它不是一个世界上可访问的文件,它当然不应该是Web访问。 我的意思是你要么a)告诉你的web服务器不要提供你的configuration文件( IIS已经用web.config文件做这个,并且提供一个HTTP 404.8的状态而不是内容)或者b)把它移到你的web服务目录。 如果有人可以看到你的configuration文件,那么比在源代码中看到的更糟糕。

configuration文件的基本版本(空的/默认的)也是一个好主意,并且在每个环境中分离出来,这样你可以为生产,开发和testing平台configuration不同的configuration文件。

环境variables是区分这些环境的最常见方式,如下面的代码所示:

 // Check if it's been set by the web server if (!empty($_ENV['ENVIRONMENT'])) { // Copy from web server to PHP constant define('ENVIRONMENT', $_ENV['ENVIRONMENT']); } if (!defined('ENVIRONMENT')) { // Default to development define('ENVIRONMENT', 'development'); } // Load in default configuration values require_once 'config.default.php'; // Load in the overridden configuration file for this environment require_once 'config.' . ENVIRONMENT . '.php'; 

另一种相当常见的方式是使用XMLconfiguration文件,只读取您需要的值(将configuration文件的caching副本存储在内存中)。 这可以很容易地限制到只加载某些值,而不是允许任意包含PHP文件,总体而言,在我看来是一个更好的解决scheme,但上述应该让你开始正确的方向。

您可能会希望您的VCS忽略该文件。 另一方面,你可能需要一个文件的框架,或者有一个合理的默认值(当然,后者不适用于login数据),以受版本控制。 处理这个问题的一个常见方法是有一个签入的模板configuration文件,安装过程将该文件复制到实际configuration文件的位置,在该位置进行自定义。 这可以是手动或自动化的过程。

(虽然与主要问题有些不相干,但为你的环境引入一个常量可以让你做一些其他很酷的事情,比如推迟一个假的邮件实现,而不是实际的SMTP实现,当然这也可以通过configuration文件来完成)

一个非常好的解决scheme,如果你在Apache上,它将信息存储在虚拟主机configuration中

 SetEnv MYSQL_USER "xx" SetEnv MYSQL_PASSWORD "y2wrg435yw8" 

可以使用$_ENV[]轻松获取数据以用于代码。

正如其他人所提到的,把它放在源代码控制之外的一个单独的configuration文件中(显然这将在源代码pipe理下的代码中提到)。

在文件夹意外暴露的情况下命名文件config.php而不是config.ini也是一个好主意,这意味着文件不会被下载,而是不返回任何内容。

如果您觉得12 因子方式有价值,他们build议在环境中存储configuration。

这样做还有一个额外的好处,即允许您在testing时或在非生产环境中编写完全相同的代码 。 如果您想(或需要)更改数据库或其他任何东西,则无需修改代码 – 只需更改环境variables即可。

我会做的是只存储示例configuration文件在存储库,如config.php.dist,不要把实际config.php版本控制。

好问题。 您可以将最敏感的部分(例如键/密码)作为环境variables移出,但是这只会将问题推迟到您的服务器configuration(这大概也在存储库中)。

你也可以尝试避免像数据库这样的东西的密码,通过减less密码并将其保护在防火墙之后。 这些都不是完美的解决scheme,但他们是我所了解的方法。

将密码从代码移动到configuration文件是一个好主意,所以密码将不在存储库中。 在configuration文件中对其进行encryption的想法是有问题的,因为拥有configuration文件+ PHP代码的人可以解密它,并始终运行代码并获得明文密码。 可能最好把密码保存在一个configuration文件中作为纯文本,并考虑如何保护configuration文件免受未经授权的访问。

我在这里看不到这个问题。 如果你正在共享一个仓库,你可能不想硬编码密码和configuration。 您应该提供一个默认值:

 host: localhost user: root pass: root name: db 

如果你真的想要你可以使用和parsing一个.ini文件,但是与源代码中设置的数组相比,它可能会非常慢,而且对我来说并没有什么意义。

记住:唯一可以信任的就是你的源代码,如果他们能得到它的话,你就会被搞砸了。

您始终可以使用函数parse_ini_file创buildconfigurationini文件。