Cakephp auth component with two models session

柔情痞子 提交于 2019-12-18 13:01:12

问题


I have two cakephp2 applications running on same database, but having different Auth tables and different $this->Auth->userModel values accordingly. Authentication works well and users from one app can't log into other.

BUT.. as apps uses same CAKEPHP session cookie, this happens: when user from app 'one' logs in, it can access any Auth protected action in app 'two'!

I will probably use different user roles and cookie names. But still, why Auth component is ignoring Auth->userModel settings when checking the session? Is there a way to configure it to work right in this situation?

Thanks in advance for any suggestions.


回答1:


If not configured otherwise, AuthComponent will write the authenticated user record to the Auth.User session key in CakePHP 2. But it can be changed:

AuthComponent::sessionKey

The session key name where the record of the current user is stored. If unspecified, it will be "Auth.User".

(In CakePHP 1.3 this was different: Auth.{$userModel name})

So, if your apps share a Session, which they do, if cookie name and Security.salt match, the logged in record will be shared.

There are two possibilities to solve this:

Separate the logins

Simply set a different AuthComponent::sessionKey for your two models. This will allow them to keep the logged in user separately

Separate the sessions

Configure different Cookie names and Salts for both apps, so their sessions cannot override each other. This is probably the cleaner solution, because it also covers the risk of other session keys being double-used.




回答2:


I have a similar issue which is why I've started a bounty on this question. Basically I have a public facing part of the application which lets users login from one table and an administrative part of the application which lets admins login using a different table. My AppController looks something like this:

public $components = array(
    'Session',
    'Auth' => array(
        'autoRedirect' => false,
        'authenticate' => array(
            'Form' => array(
                'userModel' => 'User'
            )
        ),
        'loginAction' => array('controller' => 'users', 'action' => 'login'),
        'loginRedirect' => array('controller' => 'users', 'action' => 'overview'),
        'logoutRedirect' => array('controller' => 'users', 'action' => 'loggedout')
    )
);

and I have another AdminController where I have this:

public $components = array(
    'Session',
    'Auth' => array(
        'authenticate' => array(
            'CustomForm' => array(
                'userModel' => 'Admin'
            )
        ),
        'loginAction' => array('controller' => 'admin', 'action' => 'login'),
        'loginRedirect' => array('controller' => 'admin', 'action' => 'index'),
        'logoutRedirect' => array('controller' => 'home', 'action' => 'index')
    )
);

But as mentioned in this question, sessions from the two don't get along and overwrite each other. What's the best way to overcome this?




回答3:


Extend the Model/Datasource/Session/DatabaseSession.php session handler with something like MyDatabaseSession and overwrite the write and read methods. Maybe simply copy the existing code of both methods and add something like

'app_id' => Configure::read('App.appId')

to the read() conditions and do the same in the write method. And do not forget to add the field to your session database schema and to configure the session to use your handler.

<?php
App::uses('DatabaseSession', 'Model/Datasource/Session');
class ExtendedDatabaseSession extends DatabaseSession  {

    public function read($id) {
        $row = $this->_model->find('first', array(
                'conditions' => array(
                    'app_id' => Configure::read('App.appId'),
                    $this->_model->primaryKey => $id)));

        if (empty($row[$this->_model->alias]['data'])) {
            return false;
        }

        return $row[$this->_model->alias]['data'];
    }

    public function write($id, $data) {
        if (!$id) {
            return false;
        }
        $expires = time() + $this->_timeout;
        $record = compact('id', 'data', 'expires');
        $record[$this->_model->primaryKey] = $id;
        $record['app_id'] = Configure::read('App.appId');
        return $this->_model->save($record);
    }
}

I do not know your app, so were you write the app id to the config data is up to you, bootstrap or beforeFilter() maybe. You should add it before the session gets initialized I think or you'll need to re-init the session or something. I leave it up to you to look the right point up. :)



来源:https://stackoverflow.com/questions/10538159/cakephp-auth-component-with-two-models-session

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!