首页 文章

Cakephp auth组件有两个模型会话

提问于
浏览
12

我有两个在同一个数据库上运行的cakephp2应用程序,但是相应地具有不同的Auth表和不同的$ this-> Auth-> userModel值 . 身份验证效果很好,一个应用的用户无法登录其他应用 .

但是,当应用程序使用相同的CAKEPHP会话cookie时,会发生以下情况:当应用程序“one”的用户登录时,它可以访问应用程序“两个”中的任何受Auth保护的操作!

我可能会使用不同的用户角色和cookie名称 . 但是,为什么Auth组件在检查会话时忽略了Auth-> userModel设置?有没有办法将其配置为在这种情况下正常工作?

在此先感谢您的任何建议 .

3 回答

  • 0

    如果没有另外配置,AuthComponent会将经过身份验证的用户记录写入CakePHP 2中的 Auth.User 会话密钥 . But it can be changed:

    AuthComponent :: sessionKey存储当前用户记录的会话密钥名称 . 如果未指定,则为“Auth.User” .

    (在CakePHP 1.3中this was differentAuth.{$userModel name}

    因此,如果您的应用共享会话,他们会这样做,如果Cookie名称和_1182239匹配,则会共享已登录的记录 .

    有两种可能性来解决这个问题:

    分开登录

    只需为两个型号设置不同的 AuthComponent::sessionKey 即可 . 这将允许他们单独保留登录用户

    分开会话

    为两个应用程序配置不同的Cookie名称和Salt,因此它们的会话不能相互覆盖 . 这可能是更清晰的解决方案,因为它还涵盖了其他会话密钥被重复使用的风险 .

  • 2

    我有一个类似的问题,这就是为什么我开始在这个问题上获得赏金 . 基本上我有一个面向公众的应用程序部分,它允许用户从一个表和应用程序的管理部分登录,这使管理员可以使用不同的表登录 . 我的AppController看起来像这样:

    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')
        )
    );
    

    我有另一个AdminController,我有这个:

    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')
        )
    );
    

    但正如这个问题中所提到的,两者的会话并不相处并相互覆盖 . 克服这个问题的最佳方法是什么?

  • 11

    使用MyDatabaseSession之类的东西扩展Model / Datasource / Session / DatabaseSession.php会话处理程序并覆盖write和read方法 . 也许只需复制两种方法的现有代码并添加类似的东西

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

    到read()条件并在write方法中执行相同的操作 . 并且不要忘记将该字段添加到会话数据库模式和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);
        }
    }
    

    我不知道你的应用程序,所以你写的配置数据的配置ID取决于你,bootstrap或beforeFilter()可能 . 您应该在会话初始化之前添加它我认为或者您需要重新启动会话或其他东西 . 我把它留给你看看正确的一点 . :)

相关问题