How to Yii app protected connection string? - php

I'm hosting a Yii app on shared-host with some my friend, and keep database in private MySQL server. As you knew, database info can be found so very easy in protected\config\main.php by another host owner (my friend and more):
'db'=>array(
'connectionString' => 'mysql:host=211.113.2.45;dbname=FamilyBook',
'emulatePrepare' => true,
'username' => root,
'password' => 'xcute445',
'charset' => 'utf8',
),
Is there any solution to conceal connection information as IP mySQL server, username, password?
May MySQL server provide RSA mechanism to protect database info?
Example, any people can see as below but cannot understand or use:
'db'=>array(
'connectionString' => '57bf064b2166366a5ea61109006b8d5c',
'emulatePrepare' => true,
'username' => '63a9f0ea7bb98050796b649e85481845',
'password' => 'e04ccf211208f8c97e4a36e584926e60',
'charset' => 'utf8',
), // value by MD5 function, example only

No, you cannot conceal the credentials from someone who has access to your source as long as you are using native MySql authentication. That's because your code needs to pass the credentials as cleartext¹ to the server, so it needs to be able to "decrypt" them before connecting. Someone who has access to your source can follow the same procedure and decrypt them as well.
You could secure your system by relying on some type of PAM authentication instead of user-supplied credentials, but Yii does not support such.
¹note: This is not actually true. The client passes a hash to the server, but it needs to have access to the original password in order to hash it. This means that for the purposes of this discussion it makes no difference (it would make a difference for someone who is listening on the network).

Using Yii 1.x I did it using below method.
create a class, DbConnection inside protected/components extending from CDbConnection
class DbConnection extends CDbConnection
{
public function createPdoInstance()
{
// Decrypt the password used in config file
// e.g.: $this->password = mydecrypt($this->password);
return parent::createPdoInstance();
}
}
Adjust the config file (protected/config/main.php)
'db' => array(
'class' => 'DbConnection', // Use above classname
'password' => 'encryptedpassword',
),

Related

How to set second database in laravel when main connection is down

I have a laravel project with many connections to different IP's.
I want laravel to connect to a backup database in the case that the main SQL server was down
Example.
192.168.1.2 -> SQL DB #1
192.168.1.3 -> SQL DB #1 Backup
If 192.168.1.2 goes down, laravel must connect to 192.168.1.3
I'd like to do this in database.php file, but I think that's impossible.
I was trying to test connection before make a query like this:
if(DB::connection('connection')->getDatabaseName())
but it seems that it save data in cache and it still throw database name even if I shutdown the SQL server
For this answer, I'm considering Laravel 5.
By debugging a model query, I've found out that Laravel connections support not a single host, but a list of them.
[
'driver' => 'sqlsrv',
'host' => [
'192.168.1.2',
'192.168.1.3',
],
'database' => 'database_name',
'username' => 'username',
'password' => 'password',
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
'transaction_isolation' => PDO::SQLSRV_TXN_READ_UNCOMMITTED, // Not required, but worth mentioning it's possible to define it here too
'options' => [],
]
The underlying method behind Laravel connections resolving is Illuminate\Database\Connectors::createPdoResolverWithHosts which has the following behavior:
protected function createPdoResolverWithHosts(array $config)
{
return function () use ($config) {
foreach (Arr::shuffle($hosts = $this->parseHosts($config)) as $key => $host) {
$config['host'] = $host;
try {
return $this->createConnector($config)->connect($config);
} catch (PDOException $e) {
continue;
}
}
throw $e;
};
}
Such behavior means that Laravel will randomly pick one of the connection's hosts and try to connect to them. If the attempt fails, it keeps trying until no more hosts are found.
You could define two mysql connections in app/config/database.php
and using a middleware you could define the db that should be connected to.
You can find a more elaborate explanation in this URL:
http://fideloper.com/laravel-multiple-database-connections
i recently started searching for the same thing and to change the connection as soon as possible you can either
add the check inside a service provider
or through a global middleware
try{
\DB::connection()->getPdo(); // check if we have a connection
}catch{
\DB::purge(config('database.default')); // disconnect from the current
\DB::setDefaultConnection('my-fallback-db'); // connect to a new one
}
also check laravel api docs for more info.

Migrate multiple databases with Propel

I am maintaining a system with many databases. One “central" db, and many other “client” dbs. Each time a client registers, we create a client db using an SQL file. The system is using Propel + PHP + MySQL.
Now the problem is, there are changes when we do version-up. It’s possible to use Propel migration for central db, but there are MANY client dbs, and in propel.yaml/ propel-config.php we only have ONE connection string for client like this:
$manager = new \Propel\Runtime\Connection\ConnectionManagerSingle();
$manager->setConfiguration(array(
'classname' => 'Propel\\Runtime\\Connection\\ConnectionWrapper',
'dsn' => 'mysql:host=127.0.0.1;dbname=' . $shopDbName . ';charset=UTF8',
'user' => 'dba',
'password' => ‘******',
'attributes' =>
array(
'ATTR_EMULATE_PREPARES' => false,
),
));
in which $shopDbName is the global variable identified by a string sent from client devices.
So, how can I automate the process of migration for client dbs in this case, please?

Trying to connect to database

I'm working on a rewrite of a project from the ground up and figured I would try to learn MVC along the way. In this case, I've chosen Phalcon and am still working through the fundamentals of converting the tutorials to my own project.
I have two "configuration" settings that I need to account for. First, I need to read a configuration file that has the database credentials (this works properly).
require_once('../fileconfig.php'); // Read config file
$init = new Phalcon\Config\Adapter\Php("../fileconfig.php"); //Convert it to array
But once I have that, how do I actually connect to the database and add it to $di-> (which, if I understand correctly, is effectively the global class? Ultimately, I want to pull the contents of "select * from config" into an array and use that for the application configuration. In this case, var_dump($dbh) returns "null"
//Connect to database
$di->set('db', function() use ($init) {
$dbh = new \Phalcon\Db\Adapter\Pdo\Mysql([
"host" => $init->database->host,
"username" => $init->database->username,
"password" => $init->database->password,
"dbname" => $init->database->dbname
]);
return $dbh;
});
var_dump($dbh); //returns null
If I remove the $di-> section, the array returns the data that I need, but it still doesn't help me figure out how to connect to the database and have it available globally for other functions in the models:
$dbh = new \Phalcon\Db\Adapter\Pdo\Mysql([
"host" => $init->database->host,
"username" => $init->database->username,
"password" => $init->database->password,
"dbname" => $init->database->dbname
]);
Returns:
object(Phalcon\Db\Adapter\Pdo\Mysql)[28]
protected '_descriptor' =>
array (size=4)
'host' => string 'localhost' (length=9)
'username' => string 'testuser' (length=8)
'password' => string 'testpass' (length=8)
'dbname' => string 'testdb' (length=6)
This question seems to be close to what I'm asking, but was more about error handling than the actual connection and I didn't see an answer to my question there.
To resolve your database you need to resolve your di. You could resolve it the file you declared it in with
$di->getShared('db')
But note, you don't want to do that. You want your files seperated with their responsibilities.
Inside of a class that inherits \Phalcon\Mvc\Controller you can use
$this->db->
Please refer to http://docs.phalconphp.com/en/latest/reference/di.html in order to see why to use a DI, and all the nuances of accessing it
It really helps to go through other phalcon projects and look at how everything works together. Please refer to the source here and look at how projects are set up:
https://github.com/phalcon/invo
https://github.com/phalcon/vokuro
https://github.com/phalcon/forum
These are ranked by complexity so start with invo first and then move on

YII, MS Access how can i use it together?

I want use Yii and MS Access together, but I don't know how..
I can use ODBC without Yii like this
$link = odbc_connect($name, $user, $pass)
but now i need it in Yii, like MySQL:
'db'=>array(
'connectionString' => 'mysql:host=localhost;dbname=ex1c',
'emulatePrepare' => true,
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'tablePrefix' => 'ex1c_',
)
what should i write in connection string
may be need something software setup in computer
how to set it?
If I'm understanding your question right, you have one set of data that you want to be able to reference from a YII application and from MS Access. The best approach I can think of here is to:
Put the data into a MySQL database
Have YII access it directly as you illustrate above
Set up the MySQL ODBC driver on the Windows machine where you are running access, and point Access at MySQL via that driver
Here is a pointer to MyODBC, which will provide the critical linkage between Access and MySQL:
http://dev.mysql.com/downloads/connector/odbc/

system.db.CDbConnection taking more than 1 second to execute in yii

I am a new to yii although i have worked a lot with codeigniter and was just trying to convert my code from codeigniter to yii
But the CDbconnection is taking more than 1 second to execute i have attached a screenshot.
also the sql code i am using.
$criteria = new CDbCriteria();
$criteria->select = "total_photos";
$data = array( 'Gallerys' => Gallerynames::model()->findAll($criteria));
Please look into it
Edit:
Here is my db config
'db'=>array(
'class' => 'system.db.CDbConnection',
'connectionString' => 'mysql:host=localhost;dbname=yiiwiki',
'emulatePrepare' => true,
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'enableProfiling' => true,
'schemaCachingDuration' => 3600,
),
From yii guide
Because ActiveRecord relies on the metadata about tables to determine
the column information, it takes time to read the metadata and analyze
it. This may not be a problem during development stage, but for an
application running in production mode, it is a total waste of time if
the database schema does not change.
so set the schemaCachingDuration of the db application component a value greater than zero.
'db'=>array(
'class'=>'system.db.CDbConnection',
'connectionString'=>'sqlite:/wwwroot/blog/protected/data/blog.db',
'schemaCachingDuration'=>3600,
),
Keep in mind that you should specify a valid cache in the application config
EDIT
It seems your problem is not due to the schema. Refering to this changing localhost to 127.0.0.1 will fix it

Categories