Php ZF2-假设其他用户';身份

Php ZF2-假设其他用户';身份,php,zend-framework,zend-framework2,Php,Zend Framework,Zend Framework2,在我开始重新发明轮子之前,我首先想检查ZF2是否支持这种特定的用例,即管理员以其他用户身份登录,或者假定他们的身份 如果没有,因为我不熟悉ZF2内部设计,我将如何实现它,唯一的限制是系统已经构建,因此我无法更改组件(控制器、身份验证服务等)以支持它 我的第一个想法是建立一种机制,将存储在会话存储器中的已记录用户信息与我想要假定其身份的用户信息进行切换。然后,将原始用户信息(admin)写入另一个名称空间下的会话,以便可以还原 按照这种方法,我希望像Zend\Authentication\Auth

在我开始重新发明轮子之前,我首先想检查ZF2是否支持这种特定的用例,即管理员
以其他用户身份登录,或者
假定他们的身份

如果没有,因为我不熟悉ZF2内部设计,我将如何实现它,唯一的限制是系统已经构建,因此我无法更改组件(控制器、身份验证服务等)以支持它

我的第一个想法是建立一种机制,将存储在会话存储器中的已记录用户信息与我想要假定其身份的用户信息进行切换。然后,将原始用户信息(admin)写入另一个名称空间下的会话,以便可以还原

按照这种方法,我希望像
Zend\Authentication\AuthenticationService
这样的组件返回我假设的用户身份。因此,在我对其他控制器中的
$this->identity()->getId()
(identity是AuthenticationService的控制器插件,它返回
用户
)的每次调用中,业务逻辑都将正常工作

说到这里,问题是:

  • 已经有解决方案了吗
  • 我的方法是否正确,通过覆盖会话存储,我可以假定其他用户ID,并期望ZF2组件相应地工作,或者是否有任何关于ZF2内部设计/基础架构的考虑因素我没有考虑到我应该考虑
  • 也许有更好的办法

  • 我认为您需要创建自己的AuthenticationAdapter

    class AdminUserLoginAsUser implements \Zend\Authentication\Adapter\AdapterInterface
    {
    
        /**
         * @var User
         */
        private $userToLoginAs;
    
        /**
         * @var AdminUser
         */
        private $adminUser;
    
        public function __construct(User $userToLoginAs, AdminUser $adminUser)
        {
    
            $this->userToLoginAs = $userToLoginAs;
            $this->adminUser = $adminUser;
        }
    
        /**
         * Performs an authentication attempt
         *
         * @return \Zend\Authentication\Result
         * @throws \Zend\Authentication\Adapter\Exception\ExceptionInterface If authentication cannot be performed
         */
        public function authenticate()
        {
            return new \Zend\Authentication\Result(
                Result::SUCCESS, $this->user, [
                    'You have assumed control of user.',
                ]
            );
        }
    }
    
    当与Zend的AuthenticationService类一起使用时,上述类将允许您作为另一个用户登录

    您将需要某种方式来使用Zend的AuthenticationService类,我建议使用围绕AuthenticationService的AuthManager

    /**
     * The AuthManager service is responsible for user's login/logout and simple access
     * filtering. The access filtering feature checks whether the current visitor
     * is allowed to see the given page or not.
     */
    class AuthManager
    {
        /**
         * Authentication service.
         * @var \Zend\Authentication\AuthenticationService
         */
        private $authService;
    
        /**
         * Session manager.
         * @var Zend\Session\SessionManager
         */
        private $sessionManager;
    
        /**
         * Contents of the 'access_filter' config key.
         * @var array
         */
        private $config;
    
        /**
         * Constructs the service.
         */
        public function __construct($authService, $sessionManager, $config)
        {
            $this->authService = $authService;
            $this->sessionManager = $sessionManager;
            $this->config = $config;
        }
    
        /**
         * Performs a login attempt. If $rememberMe argument is true, it forces the session
         * to last for one month (otherwise the session expires on one hour).
         */
        public function login($email, $password, $rememberMe)
        {
            // Check if user has already logged in. If so, do not allow to log in
            // twice.
            if ($this->authService->getIdentity()!=null) {
                throw new \Exception('Already logged in');
            }
    
            // Authenticate with login/password.
            $authAdapter = $this->authService->getAdapter();
            $authAdapter->setEmail($email);
            $authAdapter->setPassword($password);
            $result = $this->authService->authenticate();
    
            // If user wants to "remember him", we will make session to expire in
            // one month. By default session expires in 1 hour (as specified in our
            // config/global.php file).
            if ($result->getCode()==Result::SUCCESS && $rememberMe) {
                // Session cookie will expire in 1 month (30 days).
                $this->sessionManager->rememberMe(60*60*24*30);
            }
    
            return $result;
        }
    
        public function loginAsUser($user)
        {
            // Check if user has already logged in. If so, do not allow to log in
            // twice.
            if ($this->authService->getIdentity() !== null) {
                throw new \Exception('Not logged in.');
            }
    
            // First need to logout of current user
            $this->authService->clearIdentity();
    
            $authAdapter = $this->authService->setAdapter(new AdminUserLoginAsUser($user, $this->authService->getIdentity()));
            return $this->authService->authenticate();
    
        }
    
        /**
         * Performs user logout.
         */
        public function logout()
        {
            // Allow to log out only when user is logged in.
            if ($this->authService->getIdentity()==null) {
                throw new \Exception('The user is not logged in');
            }
    
            // Remove identity from session.
            $this->authService->clearIdentity();
        }
    
    }
    
    要了解如何将其全部连接在一起,我建议查看以下资源:

    这些资源用于zf3,但我认为用户身份验证和管理身份验证与zf2非常相似