简体   繁体   English

CakePHP Auth组件使用2个表

[英]CakePHP Auth Component Using 2 Tables

CakePHP Version 1.2.5 CakePHP版本1.2.5

I would like a single user to have multiple email addresses. 我希望单个用户拥有多个电子邮件地址。
I would like a single user to have a single password. 我希望单个用户拥有一个密码。
I would like users to log in using any of their multiple email addresses and their single password. 我希望用户使用他们的多个电子邮件地址和他们的单个密码登录。

I have created a users table with an id and a password field. 我创建了一个带有id和密码字段的用户表。
I have created a user_email_addresses table with an id field a user_id field and an email_address field. 我创建了一个user_email_addresses表,其id字段是user_id字段和email_address字段。

Question: 题:
How do I modify the auth component minimally to look for the "username" in this case, "email_address", in the user_email_addresses table and the "password" in the users table? 如何最小化修改auth组件以查找user_email_addresses表中的“username”“email_address”和users表中的“password”?

Seems as though modifying the identify method in the auth component might do it. 似乎修改auth组件中的identify方法可能会这样做。 But I think modifying the auth component directly is a bad idea - any ideas on how to extend and still possibly modify the identify method? 但我认为直接修改auth组件是一个坏主意 - 关于如何扩展并仍然可能修改标识方法的任何想法? http://cakebaker.42dh.com/2009/09/08/extending-cakephps-core-components/ or possibly nominate a different authenticate object? http://cakebaker.42dh.com/2009/09/08/extending-cakephps-core-components/或可能提名不同的身份验证对象?

Starting line 774: 第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;
}

AuthComponent::identify() takes two parameters, $user and $conditions AuthComponent::identify()接受两个参数, $user$conditions

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

Looking at the above snippet, if you pass false as the $conditions , the method will execute with no model conditions. 看着上面的代码中,如果传递false$conditions ,该方法将没有模型条件执行。

Also, looking at the rest of the code, if you pass a $user value of type string , it won't execute most of the user-related code until it gets here: 另外,查看其余代码,如果传递类型为string$user值,它将不会执行大多数与用户相关的代码,直到它到达:

} 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;
        }
}

Here it runs Model::escapeField() , with no parameters, which returns an escaped version of User.id (by default) and maps this field to the string that was passed in. It then merges this with the $conditions array and performs a Model::find() . 这里运行Model::escapeField() ,没有参数,返回User.id的转义版本(默认情况下),并将此字段映射到传入的字符串。然后将其与$conditions数组合并执行一个Model::find()

It should be safe to say that if the string is the user's ID and there are no conditions it will find the person with that ID every time. 应该可以肯定地说,如果字符串是用户的ID并且没有条件,则每次都会找到具有该ID的人。

As such, you should be able to extend AuthComponent to do what you want like so: 因此,您应该能够扩展AuthComponent以执行您想要的操作:

// app/controllers/components/app_auth.php
<?php
App::import('Component', 'Auth');
class AppAuthComponent extends AuthComponent {
/**
 * Custom user identification
 */
    function identify($user=null, $conditions=null) {
        // get the model AuthComponent is configured to use
        $model =& $this->getModel(); // default is User
        // do a query that will find a User record when given successful login data
        $user = $model->find('first', array('conditions' => array(
            'EmailAddress.' . $this->fields['username'] => $user[$this->userModel][$this->fields['username']],
            'User.' . $this->fields['password'] => $user[$this->userModel][$this->fields['password']],
        ));
        // return null if user invalid
        if (!$user) {
            return null; // this is what AuthComponent::identify would return on failure
        }
        // call original AuthComponent::identify with string for $user and false for $conditions
        return parent::identify($user[$this->userModel][$model->primaryKey], false);
    }
}
?>

You will have to replace all references to Auth with AppAuth in your application unless you follow this handy tip (the approach in the comments is nice). 除非您按照这个方便的提示 (评论中的方法很好),否则您将不得不在应用程序中替换所有对Auth的引用和AppAuth。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM