CakePHP:无法在身份验证模块上设置自定义查找器

CakePHP: Cant set custom finder on auth module

版本:4.2.9

我已按照本教程设置登录。 https://book.cakephp.org/authentication/2/en/index.html

问题是,我的自定义查找器没有被识别,因为在调试消息中我看到没有连接到用户数据 table。

这是我的错误查询,因为未加入用户数据 table。

SELECT Users.ID AS Users__ID, Users.UUID AS Users__UUID, Users.PasswordHashed AS Users__PasswordHashed, Users.Role AS Users__Role, Users.ReleaseGroup AS Users__ReleaseGroup FROM users Users WHERE Users.email = :c0 LIMIT 1

在我的 UsersTable.php

    public function initialize(array $config): void
    {
        parent::initialize($config);

        $this->setTable('users');
        $this->setDisplayField('ID');
        $this->setPrimaryKey('ID');
        $this->hasOne('Userdata');
    }

    public function findAuth(\Cake\ORM\Query $query, array $options) {
      return $query->contain('Userdata');
    }

在我的 UsersController.php

    public function beforeFilter(\Cake\Event\EventInterface $event)
    {
        parent::beforeFilter($event);
        // Configure the login action to not require authentication, preventing
        // the infinite redirect loop issue
        $this->Authentication->addUnauthenticatedActions(['login']);
    }

    public function login()
    {
        $this->request->allowMethod(['get', 'post']);
        $result = $this->Authentication->getResult();
        // regardless of POST or GET, redirect if user is logged in
        if ($result->isValid()) {
            // redirect to /articles after login success
            $redirect = $this->request->getQuery('redirect', [
                'controller' => 'Articles',
                'action' => 'index',
            ]);

            return $this->redirect($redirect);
        }
        // display error if user submitted and authentication failed
        if ($this->request->is('post') && !$result->isValid()) {
            $this->Flash->error(__('Invalid username or password'));
        }
    }

在我的AppController.php

    public function initialize(): void
    {
        parent::initialize();

        $this->loadComponent('RequestHandler');
        $this->loadComponent('Flash');
        $this->loadComponent('Authentication.Authentication');

        $this->loadComponent('Auth', [
            'authorize'=> 'Controller',
            'authenticate' => [
                'Form' => [
                    'fields' => [
                        'username' => 'fmail',
                        'password' => 'password'
                    ],
                    'finder' => 'auth',
                ]
            ],
             //use isAuthorized in Controllers
            'authorize' => ['Controller'],
             // If unauthorized, return them to page they were just on
            'unauthorizedRedirect' => $this->referer()
        ]);

在我的src/Application.php

    public function bootstrap(): void
    {
        // Call parent to load bootstrap from files.
        parent::bootstrap();
        $this->addPlugin('Authentication');
        if (PHP_SAPI === 'cli') {
            $this->bootstrapCli();
        } else {
            FactoryLocator::add(
                'Table',
                (new TableLocator())->allowFallbackClass(false)
            );
        }

        /*
         * Only try to load DebugKit in development mode
         * Debug Kit should not be installed on a production system
         */
        if (Configure::read('debug')) {
            $this->addPlugin('DebugKit');
        }

        // Load more plugins here
    }

    public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
    {
        $middlewareQueue
            // ... other middleware added before
            ->add(new RoutingMiddleware($this))
            // add Authentication after RoutingMiddleware
            ->add(new AuthenticationMiddleware($this));

        return $middlewareQueue;
    }


    public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
{
    $authenticationService = new AuthenticationService([
        'unauthenticatedRedirect' => Router::url('/users/login'),
        'queryParam' => 'redirect',
    ]);

    // Load identifiers, ensure we check email and password fields
    $authenticationService->loadIdentifier('Authentication.Password', [
        'fields' => [
            'username' => 'email',
            'password' => 'password',
        ],
    ]);

    // Load the authenticators, you want session first
    $authenticationService->loadAuthenticator('Authentication.Session');
    // Configure form data check to pick email and password
    $authenticationService->loadAuthenticator('Authentication.Form', [
        'fields' => [
            'username' => 'email',
            'password' => 'password',
        ],
        'loginUrl' => Router::url('/users/login'),
    ]);
    return $authenticationService;
}

这里是我的问题3.x(旧)的解决方案

感谢您推动正确的方向。

从我的 AppControler.php

中删除了旧的 loadComponent
    public function initialize(): void
    {
        parent::initialize();

        $this->loadComponent('RequestHandler');
        $this->loadComponent('Flash');
        $this->loadComponent('Authentication.Authentication');


        /*
         * Enable the following component for recommended CakePHP form protection settings.
         * see https://book.cakephp.org/4/en/controllers/components/form-protection.html
         */
        //$this->loadComponent('FormProtection');
    }

在 UsersTable.php

中将表格与自定义 binding/foreign-key 相关联
    public function initialize(array $config): void
    {
        parent::initialize($config);

        $this->setTable('users');
        $this->setDisplayField('ID');
        $this->setPrimaryKey('ID');
        $this->hasOne('Userdata', [
                'bindingKey' => 'UUID',
                'foreignKey' => 'UUID',
            ]);
    }


    public function findForAuthentication(\Cake\ORM\Query $query, array $options): \Cake\ORM\Query
    {
        return $query->contain('Userdata');
    }

并在我的 src/Application.php

中定义了我的自定义解析器
    // Load identifiers, ensure we check email and password fields
    $authenticationService->loadIdentifier('Authentication.Password', [
      'fields' => [
          'username' => 'userdata.email',
          'password' => 'PasswordHashed',
      ],
      'resolver' => [
          'className' => 'Authentication.Orm',
          'userModel' => 'Users',
          'finder' => 'forAuthentication',
      ],
    ]);

谢谢