【问题标题】:Auth.afterIdentify is not firingAuth.afterIdentify 没有触发
【发布时间】:2024-05-16 18:05:01
【问题描述】:

我需要在用户会话启动后对其进行更改。这是暂时的,所以使用Auth.afterIdentify 之类的事件是我正在寻找的。​​p>

我尝试了什么

我有什么

这是我目前的src/Controller/AppController.php

<?php
namespace App\Controller;

use Cake\Controller\Controller;
use Cake\Event\Event;

class AppController extends Controller implements \Cake\Event\EventListenerInterface
{

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

        // …

        $this->loadComponent('Authentication.Authentication');
        // Trying with an anonymous function
        \Cake\Event\EventManager::instance()->on('Auth.afterIdentify', function ($event) {
            Log::write( // noticed when posting this question, should have thrown an error
                'info',
                'Testing: ' . $event->getSubject()->id
            );
            debug($event);exit;
        });
        // Trying a controller callback
        \Cake\Event\EventManager::instance()->on('Auth.afterIdentify', [$this, 'afterIdentify']);
    }

    public function beforeFilter(\Cake\Event\Event $event)
    {
        parent::beforeFilter($event);
        $this->set('myAuth', $this->Authentication->getResult());
        $this->set('myUser', $this->Authentication->getIdentity());
    }

    public function afterIdentify(CakeEvent $cakeEvent, $data, $auth) {
        debug([
            '$cakeEvent' => $cakeEvent,
            '$data' => $data,
            '$auth' => $auth,
        ]);exit;
    }

    public function implementedEvents()
    {
        return [
            'Auth.afterIdentify' => 'afterIdentify',
        ] + parent::implementedEvents();
    }

}

什么不起作用

似乎没有调用上述事件侦听器。尽管正常工作,但没有更新 CakePHP 日志(甚至没有错误)。

我预期会发生什么

  • 调用 Log::write 而不声明它的来源应该会引发(并记录)错误
  • debug() 信息未显示
  • 删除public function afterIdentify 方法应该会导致错误;它没有——意味着控制器甚至没有在寻找它

【问题讨论】:

    标签: cakephp cakephp-3.0


    【解决方案1】:

    您将旧的身份验证组件和新的身份验证插件混为一谈,Auth.afterIdentify 事件属于前者。

    身份验证插件的身份验证组件有一个Authentication.afterIdentify 事件,但这仅适用于有状态且不实现自动持久化的身份验证器。所以开箱即用,这只适用于Form 身份验证器,并且在通过表单对用户进行身份验证的请求上触发事件一次,在随后通过Session 身份验证器进行身份验证的请求上,事件没有被触发。

    public function initialize()
    {
        parent::initialize();
    
        // ...
    
        $this->loadComponent('Authentication.Authentication');
    
        $this->Authentication->getEventManager()->on(
            'Authentication.afterIdentify',
            function (
                \Cake\Event\EventInterface $event,
                \Authentication\Authenticator\AuthenticatorInterface $provider,
                \Authentication\IdentityInterface $identity,
                \Authentication\AuthenticationServiceInterface $service
            ) {
                // ...
                
                $identity['foo'] = 'bar';
                $this->Authentication->setIdentity($identity);
            }
        );
    }
    

    【讨论】:

    • 一如既往,谢谢!快速提问:1. 如果我 e.g. log in as another user programmaticallyAuthentication.afterIdentify 不会被解雇? 2. 如果身份验证已移出到cakephp/authentication/4.2/namespace-Cake.Auth.html 预计会失效吗?
    • @aexl 1) 它不会(如果会,那么所示示例将导致无限循环),该事件在组件的 beforeFilter() 回调中触发. 2) 是的,旧的 auth 组件已被弃用,将在 CakePHP 5.0 中删除。
    • 看起来该事件的文档确实存在,但是如果您只搜索 afterIdentify ,那么无聊的图书搜索就找不到它:/
    • Google 似乎可以找到这些文档,但它们的另一个问题是它们的 have no mentionAuthentication.logout 事件的 was actually implemented。无论哪种方式,没什么大不了的,四处搜索仍然有帮助,所以我得到了答案:) 再次感谢您的帮助!