表单接收电子邮件和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,要么让表单直接查看关联类的“地址”属性。如何将身份验证指向另一个表中的属性,如
由于
答案 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组件配置userModel
,finder
和$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
策略通过hasOne
或join
关联与username
相关联。
另请注意,email
字段设置为address
,就像您的示例表单一样,您也可以将它们都设置为username
(或您实际喜欢的任何内容),它会不会影响查找程序查询,因为它会创建一个新查询,并使用通过配置字段从请求数据中提取的用户名值(提取的值将始终传递到{{1}的$options
键中数组,除非finder
配置是一个已经有一个名为username
的键的数组。
另见