heron
heron

Reputation: 3661

Yii database connection issue

Task

What I need is, to authenticate user based on Oracle DB user system:

I'm using Yii framework.

What I've done ...

I removed db component from protected/config/main.php file. Based on Larry Ulman's blog post replaced authenticate (which located in protected/components/UserIdentity.php) with following one

public function authenticate()
{
 $dsn='oci:dbname=XE;charset=UTF8';
 $connection=new CDbConnection($dsn,$this->username,$this->password);
 $connection->active=true;
 return $connection->getConnectionStatus();
}

Well it didn't establish any connection. BTW in server I tested with oracle client. All works well.

Questions are

  1. I'm not sure if I'm doing it in right manner.
  2. How to make established db connection persistent over whole application?

BTW

My development environment Oracle DB and Apache 2.2.4 + PHP 5.4 webserver working on Windows Server 2003.

Upvotes: 0

Views: 1612

Answers (1)

Michael Härtl
Michael Härtl

Reputation: 8587

It took some time to understand what you want. So basically it's like:

  • A user tries to log in with username/password
  • To authenticate the user, you check, whether you can establish a DB connection using that same username/password as DB credentials
  • If the connection could be opened, the user should have a db component available, that uses this same connection credentials throughout the user session

Your approach to create a custom UserIdentity is right. They are meant for doing the authentication. I'm not sure, why your code there fails, but you're on the right track. Maybe getConnectionStatus() does not work right for Oracle. You could try to execute another simple SQL command for a test.

If you've managed to test for a successful connection, you should store the username and password in the user session, e.g.

Yii::app()->user->setState('__db_username',$this->username);
Yii::app()->user->setState('__db_password',$this->password);

Now to have the db component available after login is a bit tricky. You can take different approaches. I'll describe two:

1. Create a custom CDbConnection

class DynamicDbConnection extends CDbConnection
{
    public function init()
    {
        $this->username = Yii::app()->user->getState('__db_username');
        $this->password = Yii::app()->user->getState('__db_password');

        if(!$this->username || !$this->password) {
            throw new CException('No username/password available! User not logged in?');
        }
        parent::init();
     }
}

Now you can configure this as db component in your main.php without username and password, of course:

'components' => array(
    'db' => array(
        'class' => 'DynamicDbConnection',
        'connectionString' =>'oci:dbname=XE;charset=UTF8',
    ),
 ),

2. Adding a CDbConnection from Controller::init()

You could add a db component from your base controllers init() method:

class Controller extends CController
{
    public function init()
    {
        $username = Yii::app()->user->getState('__db_username');
        $password = Yii::app()->user->getState('__db_password');

        if($username && $password) {
            Yii::app()->setComponent('db', array(
                'username' => $username,
                'password' => $password,
            ));
        }
        parent::init();
   }

You also still need a base db component configuration in your main.php for this.

Both approaches may need a little tweaking as i've not tested this. But you should get the basic idea.

Upvotes: 1

Related Questions