Authコンポーネントで複数カラムを参照する


いろいろ調べてなんとかできたのでメモ。
参照したいカラムは「username」と「email」で、どちらかが一致すればログインできる。

環境

CakePHP 3.6.12
PHP 7.2.6

必要なファイルはbakeで生成済み。

ソース

src\Controller\AppController.php
class AppController extends Controller
{
    public function initialize()
    {
        parent::initialize();

        $this->loadComponent('RequestHandler');
        $this->loadComponent('Auth', [
            'authorize'=> 'Controller',
            'authenticate' => [
                'Form' => [
                    'fields' => [
                        'username' => 'username',
                        'password' => 'password'
                    ],
                    'finder' => 'auth'
                ]
            ], 'loginAction' => [
                'controller' => 'Users',
                'action' => 'login'
            ], 'unauthorizedRedirect' => $this->referer()
        ]);
    }
}
src\Controller\UserController.php
class UsersController extends AppController
{
    public function login()
    {
        if ($this->request->is('post')) {
            $username = $this->request->getData('username');
            if (strstr($username, '@')) {
                $this->request = $this->request->withData('email', $username);
                $this->Auth->setConfig('authenticate', [
                    'Form' => ['fields' => ['username' => 'email']]
                ]);
            }
            $user = $this->Auth->identify();
            if ($user) {
                $this->Auth->setUser($user);
                return $this->redirect($this->Auth->redirectUrl());
            }
            $this->Flash->error('ユーザー名またはパスワードが不正です。');
        }
    }
}
src\Model\Table\UsersTable.php
class UsersTable extends Table
{
    // 以下を丸ごと追加
    public function findAuth(\Cake\ORM\Query $query, array $options)
    {
        $query->where(['Users.enabled' => 1]); // enabledが1のユーザーのみ取得
        return $query;
    }
}
src\Template\Users\login.ctp
<?php
    echo $this->Form->create(null, ['autocomplete' => 'off']);
    echo $this->Form->control('username', [
        'label' => 'アカウントまたはメールアドレス'
    ]);
    echo $this->Form->control('password', [
        'label' => 'パスワード'
    ]);
    echo $this->Form->button('ログイン');
    echo $this->Form->end();
?>

$_POST[username]の中に@が含まれていたらメールアドレス、それ以外はユーザー名のカラムを参照しています。
AuthコンポーネントのsetConfigでusername => emailにしているのに、withDataで入れてあげないとクエリに入らないのがよくわからない。
詳しい方教えてください。