0

根据食谱教程,我有一个使用用户和组设置身份验证的工作示例。我有一个额外的 Locations 表,它与我的 Groups 相关联。位置有很多组。组属于位置。在 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')
        )
  );

上面的代码只有在我创建用户和位置之间的直接关联时才有效。是否可以在此处将包含与组到位置关联一起使用?

4

2 回答 2

1

如果用户没有链接到位置,但组是,你应该试试这个:

'contain'   => array('Group' => array('Location')),
于 2013-03-20T07:37:58.593 回答
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;
    }
}

如您所见 - 它在未提供包含时使用父组件。

还有一些好处:您可以提供一组字段以从结果数组中删除。只需通过“排除”键传递字段名称

如何使用组件:

    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 回答