【问题标题】:custom finder not working in CakePHP 3自定义查找器在 CakePHP 3 中不起作用
【发布时间】:2017-01-30 03:10:53
【问题描述】:

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

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

根据 CakePHP doc,我正在使用自定义查找器 auth 登录。

AppController.php中的Auth组件

    $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;
}

UsersController.php 中的 login() 操作

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

users 表中添加了一个空白列username

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 列。

【问题讨论】:

  • 我用不同的方法进行了测试,但在这里也没有工作。也许 cakephp 不支持某些版本,文档还不够。

标签: authentication cakephp cakephp-3.3


【解决方案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 =&gt; [username =&gt; 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'
  ) 

【讨论】:

  • 也尝试过select,但没有运气...用 select 更新了问题
  • 我在我的应用程序中确实做到了这一点并且它有效,您确定 ['login'] 是您的表单字段吗?...已更新。
  • 你是怎么知道在 authenticate 中同时使用 'finder' 和 'fields' 的?这就是诀窍,为此 +1,效果很好。
  • 添加fields 已开始在where(['Users.email' =&gt; $options['login']]) 行提供undefined index。和`错误:SQLSTATE [42S22]:未找到列:1054 'where 子句'中的未知列'Users.login'`还添加了上面有问题的login.ctp 视图
  • @Gaurav 那是因为你们都没有取消表单验证器生成的条件,而是添加了它们。在调用自定义查找器之前,所有选项都应用于查询,为了更改它,您必须删除/修改(Query::traverse()Query::clause()),或覆盖(Query::where() 的第三个参数)他们。另外,如前所述,不会有$options['login'],它将是$options['username'],无论您在身份验证配置中选择什么别名。
猜你喜欢
  • 2015-05-31
  • 2019-12-10
  • 2014-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-30
  • 1970-01-01
相关资源
最近更新 更多