Пользовательский искатель не работает в 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'
  ) 
Другие вопросы по тегам