2

我正在使用 CakePHP 3.3。我希望用户使用电子邮件手机号码以及密码登录

我有带有email, mobile, password, etc字段的用户表。

根据 CakePHP doc,我正在使用自定义查找器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

登录.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

和上面一样

查找身份验证()

public function findAuth(Query $query, array $options)
{
    $query
        ->orWhere(['Users.email' => $options['username']])
        ->orWhere(['Users.mobile' => $options['username']]);

    return $query;
}

现在它正在工作。username但是,即使在应用程序中不需要,为什么还要强制使用列。

4

1 回答 1

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 用于识别用户的字段。您可以使用密钥用户名和密码分别指定您的用户名和密码字段。

我自己的查询使用我的应用程序(没有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'
  ) 
于 2017-01-30T08:22:55.347 回答