我有一个小型PHP应用程序,用于在MySQL数据库中存储数据。目前,用户名/密码在PHP代码中是硬编码的。例如,我不喜欢这种情况,因为代码也可以在存储库中使用。
我最好的想法是将数据从代码移动到配置文件(从存储库中排除),并以某种方式对其进行编码,因此不能直接读取(混淆)。有没有更好易用的方法来解决这个问题?
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db('mydb');
范围:我想建立一个强大但易于使用的解决方案。我想要合理的安全性,但我不是在这里处理高度机密的数据。
备注:不再建议使用mysql_connect
函数,请参阅Stack Overflow问题 Why shouldn't I use mysql_ functions in PHP? *。我本可以更改代码示例,但由于一些注释引用了这个,我没有。但是,问题的原始性质仍然有效。
答案 0 :(得分:67)
最简单的方法是,就像你说的那样,使用配置文件。
许多框架使用此功能(Zend,CakePHP,Kohana等),这是最常用的做事方式(即使在非PHP环境中也是如此)作为带有web.config
文件的ASP.NET。这样,您还可以通过复制站点的文件将配置值从环境复制到环境,这比依赖服务器设置环境变量(很快就会丢失和遗忘)更有利。
您不应该担心密码的混淆,因为它不是一个世界可访问的文件,它当然不应该是Web可访问的。我的意思是你要么a)告诉你的web服务器不要提供你的配置文件(IIS已经用web.config
文件执行此操作并提供HTTP 404.8状态而不是内容)或者b)将其移到Web服务目录之外。如果有人能够看到您的配置文件,那么比在源代码中使用它更糟糕。
配置文件的基本(空/默认)版本以及每个环境将其分离出来也是一个好主意,这样您就可以拥有一个不同的配置文件用于生产,开发和测试平台。
环境变量是区分这些环境的最常用方法,如下面的代码:
// 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';
另一种非常常见的方法是使用XML配置文件,只读取您需要的值(在内存中存储配置文件的缓存副本)。这很容易被限制为只加载某些值,而不是允许任意包含PHP文件,在我看来总体上是一个更好的解决方案,但上面的内容应该让你从正确的方向开始。
您可能希望VCS忽略该文件。另一方面,您可能需要文件的框架,或者具有合理默认值的框架(当然,后者不适用于登录数据),以进行版本控制。处理此问题的常用方法是使用签入的模板配置文件,并且安装过程会将该文件复制到实际配置文件的位置(自定义文件的位置)。这可以是手动或自动化过程。
(虽然与主要问题有点无关,但为您的环境引入一个常量可以让您做一些其他很酷的事情,例如推迟到假邮件实现而不是实时SMTP实现,但当然这也可以通过配置文件来完成)
答案 1 :(得分:45)
一个非常好的解决方案,如果您使用的是Apache,它可以将信息存储在虚拟主机配置中
SetEnv MYSQL_USER "xx"
SetEnv MYSQL_PASSWORD "y2wrg435yw8"
可以使用$_ENV[]
轻松获取数据,以便在代码中使用。
答案 2 :(得分:11)
正如其他人所提到的,将它放在源代码控制之外的单独配置文件中(显然这将在源代码管理的代码中提及。)
最好将文件命名为 config.php 而不是 config.ini ,以防该目录被意外暴露,这意味着文件赢了“下载,而不返回任何内容。
答案 3 :(得分:5)
如果您认为12factor方式很有价值,他们建议在环境中存储配置。
这样做的另一个好处是允许您在测试时或在非生产环境中编写完全相同的代码。如果您想要(或需要)更改数据库或其他任何内容,则无需修改代码 - 您只需更改环境变量就可以了。
答案 4 :(得分:2)
我要做的只是在存储库中存储示例配置文件,如config.php.dist,并且不要将实际的config.php置于版本控制之下。
答案 5 :(得分:2)
将密码从代码移动到配置文件是个好主意,因此密码不会存储在存储库中。在配置文件中加密它的想法是值得怀疑的,因为拥有配置文件+ PHP代码解密它的人总是可以运行代码并获得明文密码。可能最好将密码作为纯文本保存在配置文件中,并考虑如何保护配置文件免受未经授权的访问。
答案 6 :(得分:2)
好问题。您可以将最敏感的部分(例如密钥/密码)作为环境变量移出,但这只会将问题推迟到您的服务器配置(可能也在存储库中)。
您还可以尝试避免使用数据库之类的密码,通过减少密码并将其保护在防火墙后面。这些都不是完美的解决方案,但它们是我所知道的方法。
答案 7 :(得分:1)
您始终可以使用 parse_ini_file 功能创建配置ini文件。
答案 8 :(得分:1)
我在这里看不到所有这些问题。如果您正在共享存储库,则可能不希望对密码和配置进行硬编码。您应该提供一个默认值:
host: localhost
user: root
pass: root
name: db
如果你真的想要你可以使用和解析.ini
文件,但与源代码中设置的数组相比,它可能会非常慢,但实际上并没有那么多对我有意义。
请记住:您唯一可以信任的是您的源代码,如果他们能够获得它,那么您无论如何都会被搞砸。