当电子邮件和密码位于单独的表cakephp中时验证用户

时间:2017-05-03 03:58:37

标签: php mysql cakephp

表单接收电子邮件和pw

<?= $this->Form->create() ?>
<?= $this->Form->control('email') ?>
<?= $this->Form->control('password') ?>
<?= $this->Form->button('Login') ?>
<?= $this->Form->end() ?>

电子邮件在用户中存储为ID,密码在密码表中 地址是电子邮件表中存储实际电子邮件地址的属性 密码是pw是商店的地方

authenticate组件接收地址 -

$this->loadComponent('Auth', [
        'authenticate' => [
            'Form' => [
                'fields' => [
                    //here we define what is compared to be authenticated
                    'username' => 'address',    
                    'password' => 'password'
                ]
            ]...

登录功能与正常情况相同:

public function login()
{
    if ($this->request->is('post')) {

        //PUT IN STUFF HERE
        $user = $this->Auth->identify();


        if ($user) {
            $user->last_login = Time::now();//dont put this above uif statement, will automatically create a default object
            $this->Auth->setUser($user);
            $this->Flash->success('You have been successfully logged in.');
            $this->log("Login success", 'debug');
          //redirect after login
            return $this->redirect($this->Auth->redirectUrl('/users/index'));
        }
        $this->Flash->error('Your username or password is incorrect.');
        $this->log("Login FAILURE", 'debug');
    }
}`

我如何看待它,我们要么比较电子邮件ID,要么让表单直接查看关联类的“地址”属性。如何将身份验证指向另一个表中的属性,如

由于

2 个答案:

答案 0 :(得分:3)

您必须为此

创建Custom Authentication Objects
  

加载组件

$this->loadComponent('Auth', [
        'authenticate' => [
            'CustomForm' => [
                'fields' => [
                    'username' => 'address',// Field in your emails table
                    'password' => 'password',// Field in your users table
                    'myAssoc'=>'Users'// Custom Filed to get association
                ],
                'userModel' => 'Emails'
            ]...
  

在/ src / Auth /文件夹中创建一个文件CustomFormAuthenticate.php

<?php

namespace App\Auth;

use Cake\Auth\FormAuthenticate;
use Cake\Utility\Inflector;

class CustomFormAuthenticate extends FormAuthenticate
{
    public function _findUser($username, $password = null)
    {
        $result = $this->_query($username);
        $myAssoc = false;
        if (!empty($this->_config['fields']['myAssoc'])) {
            $myAssoc = $this->_config['fields']['myAssoc'];
            $result->contain([$myAssoc]);
        }

        $result = $result->first();

        if (empty($result)) {
            return false;
        }

        if ($password !== null) {
            $hasher = $this->passwordHasher();
            if($myAssoc !== false){
                $hashedPassword = $result->{Inflector::underscore(Inflector::singularize($myAssoc))}[$this->_config['fields']['password']];
            } else {
                $hashedPassword = $result->get($this->_config['fields']['password']);
            }

            if (!$hasher->check($password, $hashedPassword)) {
                return false;
            }

            $this->_needsPasswordRehash = $hasher->needsRehash($hashedPassword);
            $result->unsetProperty($this->_config['fields']['password']);
        }
        debug($result);
        return $result->toArray();
    }

}
  

确保您的EmailTable.php中有模型用户与电子邮件的关联

$this->hasOne('Users', [
    'foreignKey' => 'email_id'
]);
  

在您的登录页面

<?= $this->Form->create() ?>
<?= $this->Form->control('address') ?> // Field in your email table
<?= $this->Form->control('password') ?>// Field in your users table
<?= $this->Form->button('Login') ?>
<?= $this->Form->end() ?>

我已经测试了它并且它为我工作。

答案 1 :(得分:1)

我建议采用一种不那么具有侵入性的方式,即使用包含/加入users表的自定义查找器,并使用别名在主查询上设置password字段,或者在主实体上设置EmailsTable字段作为虚拟字段,内置验证器以这种方式检索所需的数据,这对验证者来说非常重要。

例如,在password课程中,添加这样的查找器,为public function findAuth(\Cake\ORM\Query $query, array $options) { return $this ->find() ->select([ 'Emails.id', 'Emails.address', // you may want to alias this one too 'password' => 'Users.password' ]) ->leftJoinWith('Users') ->where([ // the options is always named `username`, this is // not affected by the `fields` configuration 'Emails.address' => $options['username'] ]); } 字段选择正确的值:

fields

使用这样的查找器,您需要做的就是为auth组件配置userModelfinder$this->loadComponent('Auth', [ 'authenticate' => [ 'Form' => [ 'fields' => [ // set the field to `email`, just like in your form 'username' => 'email' ], 'userModel' => 'Emails', 'finder' => 'auth' ] // ... ] ]); 选项,例如:

Emails

此示例假定Users使用belongsTo策略通过hasOnejoin关联与username相关联。

另请注意,email字段设置为address,就像您的示例表单一样,您也可以将它们都设置为username(或您实际喜欢的任何内容),它会不会影响查找程序查询,因为它会创建一个新查询,并使用通过配置字段从请求数据中提取的用户名值(提取的值将始终传递到{{1}的$options键中数组,除非finder配置是一个已经有一个名为username的键的数组。

另见