CakePHP Auth组件使用2个表

时间:2009-11-05 00:04:16

标签: authentication cakephp cakephp-1.2

CakePHP版本1.2.5

我希望单个用户拥有多个电子邮件地址 我希望单个用户拥有一个密码 我希望用户使用他们的多个电子邮件地址和他们的单个密码登录。

我创建了一个带有id和密码字段的用户表 我创建了一个user_email_addresses表,其id字段是user_id字段和email_address字段。

问题:
如何最小化修改auth组件以查找user_email_addresses表中的“username”“email_address”和users表中的“password”?

似乎修改auth组件中的identify方法可能会这样做。但我认为直接修改auth组件是一个坏主意 - 关于如何扩展并仍然可能修改标识方法的任何想法? http://cakebaker.42dh.com/2009/09/08/extending-cakephps-core-components/或可能提名不同的身份验证对象?

第774行:

    function identify($user = null, $conditions = null) {
    if ($conditions === false) {
        $conditions = null;
    } elseif (is_array($conditions)) {
        $conditions = array_merge((array)$this->userScope, $conditions);
    } else {
        $conditions = $this->userScope;
    }
    if (empty($user)) {
        $user = $this->user();
        if (empty($user)) {
            return null;
        }
    } elseif (is_object($user) && is_a($user, 'Model')) {
        if (!$user->exists()) {
            return null;
        }
        $user = $user->read();
        $user = $user[$this->userModel];
    } elseif (is_array($user) && isset($user[$this->userModel])) {
        $user = $user[$this->userModel];
    }

    if (is_array($user) && (isset($user[$this->fields['username']]) || isset($user[$this->userModel . '.' . $this->fields['username']]))) {

        if (isset($user[$this->fields['username']]) && !empty($user[$this->fields['username']])  && !empty($user[$this->fields['password']])) {
            if (trim($user[$this->fields['username']]) == '=' || trim($user[$this->fields['password']]) == '=') {
                return false;
            }
            $find = array(
                $this->userModel.'.'.$this->fields['username'] => $user[$this->fields['username']],
                $this->userModel.'.'.$this->fields['password'] => $user[$this->fields['password']]
            );
        } elseif (isset($user[$this->userModel . '.' . $this->fields['username']]) && !empty($user[$this->userModel . '.' . $this->fields['username']])) {
            if (trim($user[$this->userModel . '.' . $this->fields['username']]) == '=' || trim($user[$this->userModel . '.' . $this->fields['password']]) == '=') {
                return false;
            }
            $find = array(
                $this->userModel.'.'.$this->fields['username'] => $user[$this->userModel . '.' . $this->fields['username']],
                $this->userModel.'.'.$this->fields['password'] => $user[$this->userModel . '.' . $this->fields['password']]
            );
        } else {
            return false;
        }
        $model =& $this->getModel();
        $data = $model->find(array_merge($find, $conditions), null, null, 0);
        if (empty($data) || empty($data[$this->userModel])) {
            return null;
        }
    } elseif (!empty($user) && is_string($user)) {
        $model =& $this->getModel();
        $data = $model->find(array_merge(array($model->escapeField() => $user), $conditions));

        if (empty($data) || empty($data[$this->userModel])) {
            return null;
        }
    }

    if (!empty($data)) {
        if (!empty($data[$this->userModel][$this->fields['password']])) {
            unset($data[$this->userModel][$this->fields['password']]);
        }
        return $data[$this->userModel];
    }
    return null;
}

1 个答案:

答案 0 :(得分:9)

AuthComponent::identify()有两个参数,$user$conditions

if ($conditions === false) {
        $conditions = null;
} elseif (is_array($conditions)) {
        $conditions = array_merge((array)$this->userScope, $conditions);
} else {
        $conditions = $this->userScope;
}

查看上面的代码段,如果您将false作为$conditions传递,则该方法将在没有模型条件的情况下执行。

另外,查看其余代码,如果传递$user类型string的值,它将不会执行大多数与用户相关的代码,直到它到达:

} elseif (!empty($user) && is_string($user)) {
        $model =& $this->getModel();
        $data = $model->find(array_merge(array($model->escapeField() => $user), $conditions));

        if (empty($data) || empty($data[$this->userModel])) {
                return null;
        }
}

此处运行Model::escapeField(),没有参数,返回User.id的转义版本(默认情况下),并将此字段映射到传入的字符串。然后将其与{合并{1}}数组并执行$conditions

如果字符串是用户的ID并且没有条件,那么每次都会找到具有该ID的人。应该是安全的。

因此,您应该能够扩展AuthComponent以执行您想要的操作:

Model::find()

除非您遵循此handy tip(评论中的方法很好),否则您必须在应用程序中用AppAuth替换对Auth的所有引用。