【问题标题】:Dynamic datasources and global in Cakephp 3?Cakephp 3 中的动态数据源和全局变量?
【发布时间】:2017-02-23 23:33:46
【问题描述】:

我有一个将被许多数据库使用的应用程序。要选择带有应用程序数据的数据库,我有一个带有连接参数(主机、用户名、密码、数据库...)的数据库

问题是这个动态创建的数据源不适用于应用程序的其余部分。

控制器代码

$data       = $this->request->data;
$connection = ConnectionManager::get("default");
$query      = "SELECT * FROM clients WHERE client_id = ".$data['codigo'];
$result     = $connection->execute($query)->fetchAll('assoc');

ConnectionManager::drop('default');            

$config = ConnectionManager::config('connection', [
        'className' => 'Cake\Database\Connection',
        'driver' => 'Cake\Database\Driver\Mysql',
        'persistent' => false,
        'host' => $result[0]['host'],
        'username' => $result[0]['username'],
        'password' => $result[0]['password'],
        'database' => $result[0]['database'],
        'encoding' => 'utf8',
        'timezone' => 'UTC',
        'flags' => [],
        'cacheMetadata' => true,
        'log' => false,
        'quoteIdentifiers' => false,
        'url' => env('DATABASE_URL', null),
    ]);

$connection = ConnectionManager::get('connection');
ConnectionManager::alias('connection', 'default');

return $this->redirect(['controller' => 'Mains', 'action' => 'index']);

在这个重定向之后,显然其他控制器没有这个数据源。

【问题讨论】:

  • 哎呀,这就是一个 SQL 注入漏洞!永远不要将用户数据直接插入查询!

标签: php cakephp controller connection cakephp-3.0


【解决方案1】:

根据请求数据中的内容交换数据库当然有点不寻常 - 但通常数据库连接只需要在 Cake 的初始设置中更早完成,因为每个控制器的连接资源已经设置为 default

如果您只交换一次,则可以在 config/bootstrap.php(Cake 通常设置它的 ConnectionManager)中管理它。

您将无法访问 $this->request,但可以从 $_REQUEST 中获取它,例如:

config/bootstrap.php 中,更改这些行:

Cache::config(Configure::consume('Cache'));
ConnectionManager::config(Configure::consume('Datasources'));
Email::configTransport(Configure::consume('EmailTransport'));

对此:

Cache::config(Configure::consume('Cache'));

ConnectionManager::config(Configure::consume('Datasources'));
$connection = ConnectionManager::get("default");
$client = TableRegistry::get('Clients')->find()
    ->where(['client_id'=> $_REQUEST['client_id']])->firstOrFail();

ConnectionManager::drop('default');

$config = ConnectionManager::config('connection', [
    'className' => 'Cake\Database\Connection',
    'driver' => 'Cake\Database\Driver\Mysql',
    'persistent' => false,
    'host' => $client->host,
    'username' => $client->username,
    'password' => $client->password,
    'database' => $client->database,
    'encoding' => 'utf8',
    'timezone' => 'UTC',
    'flags' => [],
    'cacheMetadata' => true,
    'log' => false,
    'quoteIdentifiers' => false,
    'url' => env('DATABASE_URL', null),
]);

ConnectionManager::get('connection');

Email::configTransport(Configure::consume('EmailTransport'));

已编辑:从原始 SQL 切换到 Table::find()

【讨论】:

  • 你继承了 OPs SQL 注入漏洞!
  • 我改了代码,出现了这个错误:注意(8):未定义索引:codigo [ROOT\config\bootstrap.php, line 156]。在进行配置之前,我需要通过表单获取这些数据。 cakephp 在我的表单之前读取了 bootstrap.php。
  • 啊 - 当它第一次呈现该表单时应该连接到什么数据库?默认?如果是这样,只需将 ConnectionManager::config(Configure::consume('Datasources')); 之后的所有内容都包含在一个大 if 语句 (if(!empty($_REQUEST['codigo']){) 中,直到该电子邮件行
  • 伙计,没用。我忘记删除与具有基本连接的数据库之一的直接连接
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-29
  • 1970-01-01
  • 2022-01-28
  • 2013-02-18
  • 1970-01-01
  • 1970-01-01
  • 2015-06-09
相关资源
最近更新 更多