13

私は同じデータベースで 2 つの cakephp2 アプリケーションを実行していますが、それに応じて異なる Auth テーブルと異なる $this->Auth->userModel 値を持っています。認証はうまく機能し、あるアプリのユーザーは別のアプリにログインできません。

しかし..アプリは同じCAKEPHPセッションCookieを使用するため、これが発生します.アプリ「1」のユーザーがログインすると、アプリ「2」の認証保護されたアクションにアクセスできます!

おそらく、異なるユーザー ロールと Cookie 名を使用することになるでしょう。それでも、セッションをチェックするときに Auth コンポーネントが Auth->userModel 設定を無視するのはなぜですか? この状況で正しく動作するように構成する方法はありますか?

ご提案いただきありがとうございます。

4

3 に答える 3

11

他の方法で構成されていない場合、AuthComponent は認証されたユーザー レコードをAuth.UserCakePHP 2 のセッション キーに書き込みます。ただし、これは変更できます。

AuthComponent::sessionKey

現在のユーザーのレコードが保存されているセッション キーの名前。指定しない場合は「Auth.User」になります。

(CakePHP 1.3 ではこれは異なっていましAuth.{$userModel name}た:)

そのため、アプリがセッションを共有する場合、Cookie 名とSecurity.salt一致する場合、ログイン レコードが共有されます。

これを解決するには、次の 2 つの可能性があります。

ログインを分離する

AuthComponent::sessionKey2 つのモデルに異なる設定をするだけです。これにより、ログインしているユーザーを個別に保持できます

セッションを分ける

両方のアプリに異なる Cookie 名とソルトを構成して、セッションが互いにオーバーライドできないようにします。これは、他のセッション キーが二重に使用されるリスクもカバーするため、おそらくよりクリーンなソリューションです。

于 2012-05-28T14:44:23.960 に答える
3

私は同様の問題を抱えているため、この質問に対して報奨金を開始しました。基本的に、ユーザーが 1 つのテーブルからログインできるアプリケーションの公開部分と、管理者が別のテーブルを使用してログインできるアプリケーションの管理部分があります。私の 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')
    )
);

しかし、この質問で述べたように、2 つのセッションはうまくいかず、互いに上書きします。これを克服する最善の方法は何ですか?

于 2012-05-27T04:05:27.030 に答える
0

Model/Datasource/Session/DatabaseSession.php セッション ハンドラーを MyDatabaseSession などで拡張し、書き込みメソッドと読み取りメソッドを上書きします。おそらく、両方のメソッドの既存のコードをコピーして、次のようなものを追加するだけです

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

read() 条件に追加し、write メソッドで同じことを行います。フィールドをセッション データベース スキーマに追加し、ハンドラーを使用するようにセッションを構成することを忘れないでください。

<?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()かもしれません。セッションが初期化される前に追加する必要があると思います。そうしないと、セッションなどを再初期化する必要があります。正しい点を見上げるのはあなたに任せます。:)

于 2012-05-28T06:52:41.207 に答える