Un formulario toma un correo electrónico y pw
<?= $this->Form->create() ?> <?= $this->Form->control('email') ?> <?= $this->Form->control('password') ?> <?= $this->Form->button('Login') ?> <?= $this->Form->end() ?>El correo electrónico se almacena como una ID en Usuarios, y la contraseña está en la tabla de contraseñas. La dirección es el atributo en la tabla de correos electrónicos que almacena la dirección de correo electrónico real. La contraseña es donde se almacena pw.
El componente de autenticación toma la dirección, que
$this->loadComponent('Auth', [ 'authenticate' => [ 'Form' => [ 'fields' => [ //here we define what is compared to be authenticated 'username' => 'address', 'password' => 'password' ] ]...La función de inicio de sesión es normal:
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'); } }`Como lo veo, comparamos las identificaciones de correo electrónico o obtenemos el formulario para ver directamente el atributo 'dirección' de las clases asociadas. ¿Cómo se apunta la autenticación al atributo en otra tabla como esa?
Gracias
Tienes que crear Objetos de Autenticación Personalizados para eso
Componente en carga
$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' ]...Cree un archivo CustomFormAuthenticate.php en la carpeta /src/Auth/
<?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(); } }Asegúrese de tener una asociación de usuarios modelo con correo electrónico en su EmailTable.php
$this->hasOne('Users', [ 'foreignKey' => 'email_id' ]);En su página de inicio de sesión
<?= $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() ?>Lo he probado y me funciona.
Sugeriría una forma menos intrusiva, es decir, usar un buscador personalizado que contenga / se una a la tabla de usuarios, y establezca el campo de password en la consulta principal usando un alias, o en la entidad principal como un campo virtual, de esa manera el construido -in autenticador recupera los datos que necesita, que es todo lo que importa para el autenticador.
Por ejemplo, en su clase EmailsTable , agregue un buscador como este, que selecciona el valor adecuado para el campo de 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'] ]); } Con dicho buscador, todo lo que necesita hacer es configurar los fields , el userModel de usuario y las opciones del finder para el componente de autenticación, como:
$this->loadComponent('Auth', [ 'authenticate' => [ 'Form' => [ 'fields' => [ // set the field to `email`, just like in your form 'username' => 'email' ], 'userModel' => 'Emails', 'finder' => 'auth' ] // ... ] ]); Este ejemplo asume que los Emails están asociados con los Users a través de una belongsTo a o hasOne , utilizando la estrategia de join .
También tenga en cuenta que el campo de nombre de username está configurado para email al igual que en su formulario de ejemplo, también puede configurar ambos para la address (o cualquier cosa que desee en realidad), no afectará la consulta de los buscadores, ya que crea una nueva consulta y utiliza el valor de nombre de usuario que se extrajo de los datos de la solicitud a través del campo configurado (el valor extraído siempre se pasará en la clave de nombre de username de la matriz $options , a menos que la configuración del finder sea una matriz que ya tiene una clave denominada nombre de username ).
Ver también