Пользовательский искатель не работает в CakePHP 3
Я работаю над CakePHP 3.3. Я хочу, чтобы пользователь вошел в систему, используя либо адрес электронной почты, либо номер мобильного телефона вместе с паролем.
У меня есть таблица пользователей с email, mobile, password, etc
поля.
Согласно документу CakePHP, я использую пользовательский поиск auth
чтобы залогиниться.
Auth
компонент в AppController.php
$this->loadComponent('Auth', [
'loginRedirect' => [
'controller' => 'Dashboard',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Pages',
'action' => 'home'
],
'authenticate' => [
'Form' => [
'finder' => 'auth'
]
]
]);
а также findAuth()
действие в UsersTable.php
public function findAuth(Query $query, array $options)
{
$query
->select(['id', 'email', 'mobile', 'password'])
->where(['Users.email' => $options['login']])
->orWhere(['Users.mobile' => $options['login']]);
return $query;
}
и действие login() в UsersController.php
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->registerError(__('Invalid Credentials, try again'), ['key' => 'registration']);
}
}
login.ctp
представление содержит
<?php
echo $this->Form->create();
echo $this->Form->input('login');
echo $this->Form->input('password');
echo $this->Form->submit();
echo $this->Form->end();
?>
Но это не работает и печатает Invalid Credentials, try again
Обновление 2
Добавлен пустой столбец username
в users
Таблица.
login.ctp
<?php
echo $this->Form->create();
echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Form->submit();
echo $this->Form->end();
?>
AppController.php: AuthComponent
так же, как и выше
findAuth()
public function findAuth(Query $query, array $options)
{
$query
->orWhere(['Users.email' => $options['username']])
->orWhere(['Users.mobile' => $options['username']]);
return $query;
}
Теперь это работает. Но зачем насильно использовать username
столбец, даже если не требуется в приложении.
1 ответ
Вы должны выбрать все поля, необходимые для аутентификации пользователя, как описано в doc.
public function findAuth(Query $query, array $options)
{
$query
->select(['id', 'email', 'mobile', 'username', 'password'])
->orWhere(['Users.email' => $options['login']])
->orWhere(['Users.mobile' => $options['login']]);
return $query;
}
И будь уверен $options['login']
в твоей форме.
Обновление: если вы используете 'логин' в качестве формы ввода, попробуйте использовать:
'authenticate' => [
'Form' => [
'finder' => 'auth',
'fields' => ['username' => 'login', 'password' => 'password']
]
]
fields Поля, используемые для идентификации пользователя. Вы можете использовать ключи username и password, чтобы указать свои поля username и password соответственно.
Мой собственный запрос с использованием моего приложения (без fields => [username => login]
):
SELECT
Users.id AS `Users__id`,
Users.username AS `Users__username`,
Users.password AS `Users__password`,
Users.role AS `Users__role`,
Users.email AS `Users__email`
FROM
users Users
WHERE
(
Users.email = 'user@example.com'
OR (
Users.username = 'user@example.com'
AND Users.username = 'user@example.com'
)
)
Мой логин похож, но вместо ваших полей используются имя пользователя и адрес электронной почты.
Обновление 2: документация не так велика. Таким образом, тестирование показало, что по умолчанию при использовании пользовательского поиска запрос будет изменен Cake, добавив первый WHERE this = 'something'
, то решение использует orWhere на всех остальных (findAuth модифицировано).
Новый запрос:
SELECT
Users.id AS `Users__id`,
Users.username AS `Users__username`,
Users.password AS `Users__password`,
Users.role AS `Users__role`,
Users.email AS `Users__email`
FROM
users Users
WHERE
(
Users.email = 'user'
OR Users.username = 'user'
)