0

クックブックチュートリアルに基づいて、ユーザーとグループを使用して認証を設定する実際の例があります。グループに関連付けられている追加の Locations テーブルがあります。場所には多くのグループがあります。グループは場所に属しています。2.2 では、ユーザーの位置データを取得できるはずですが、できません。

// App controller
public function beforeFilter() {

    $this->Auth->authenticate = array(
        'all' => array (
            'scope' => array('User.status' => 1)
        ),
        'Form' => array(
                'contain'   => array('Group', 'Location'),
                'fields' => array('Location.name')
        )
  );

上記のコードは、ユーザーと場所の間に直接の関連付けを作成した場合にのみ機能します。グループとロケーションの関連付けで、contain here を使用することはできますか?

4

2 に答える 2

1

BaseAuthenticateの問題は、ユーザー情報を返す方法ですreturn $result[$model];
したがって、必要に応じて、app / Controller/Authに配置された代替コンポーネントを使用しています。

App::uses('FormAuthenticate', 'Controller/Component/Auth');

class FormAndContainableAuthenticate extends FormAuthenticate {

    protected function _findUser($username, $password) {
        if (empty($this->settings['contain'])) {    //< deafult
            $userData = parent::_findUser($username, $password);
        } else {    //< with contains
            $userModel = $this->settings['userModel'];
            list($plugin, $model) = pluginSplit($userModel);
            $fields = $this->settings['fields'];
            $conditions = array(
                $model . '.' . $fields['username'] => $username,
                $model . '.' . $fields['password'] => $this->_password($password),
            );
            if (!empty($this->settings['scope'])) {
                $conditions = array_merge($conditions, $this->settings['scope']);
            }
            $modelObj = ClassRegistry::init($userModel);
            $modelObj->contain($this->settings['contain']);
            $result = $modelObj->find('first', array(
                'conditions' => $conditions
            ));
            if (empty($result) || empty($result[$model])) {
                return false;
            }
            foreach($result as $modelName => $modelData) {
                if ($modelName !== $model) {
                    $result[$model][$modelName] = $modelData;
                }
            }
            $userData = $result[$model];
        }
        // remove dangerous fields like password
        unset($userData[$this->settings['fields']['password']]);
        if (!empty($this->settings['exclude'])) {
            foreach ($this->settings['exclude'] as $fieldName) {
                unset($userData[$fieldName]);
            }
        }
        return $userData;
    }
}

ご覧のとおり、含まれているものが提供されていない場合は、親コンポーネントを使用します。

また、いくつかのボーナス:結果の配列から削除するフィールドのセットを提供できます。'exclude'キーを介してフィールド名を渡すだけです

コンポーネントの使用方法:

    public $components = array(
        'Auth' => array(
            'authenticate' => array(
                'FormAndContainable' => array(
                    'fields' => array(
                        'username' => 'username',
                        'password' => 'password',
                    ),
                    'userModel' => 'Staff',
                    'contain' => array('StaffPermission'),
                    'exclude' => array('plain_password')
                )
            ),
        ),
    );
于 2013-03-21T15:40:21.570 に答える
1

ユーザーが場所にリンクされていないが、グループがリンクされている場合は、これを試してください:

'contain'   => array('Group' => array('Location')),
于 2013-03-20T07:37:58.593 に答える