ZF3 MVC Zend \身份验证即服务工厂 [英] ZF3 MVC Zend\Authentication as a Service Factory

查看:81
本文介绍了ZF3 MVC Zend \身份验证即服务工厂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将我的ZF2 User模块适配到ZF3 MVC.它有一个身份验证服务管理器,对于每个请求(即页面加载),在Module类内的onBootsrap函数中都将调用该服务,以检查用户是否已通过身份验证.

I'm trying to adapt my ZF2 User module to ZF3 MVC. It has an authentication service manager that is called in the onBootsrap function inside the Module class for every request (i.e. page loading) to check if the user is authenticated.

由于serviceLocatorServiceAware不再可用,我正在尝试创建AuthenticationServiceFactory,但是我还没有成功.您对我做错了什么以及如何使用ZF3做到这一点有任何想法吗?

As serviceLocator and ServiceAware are not available anymore I'm trying to create an AuthenticationServiceFactory but I do not succeed yet. Would you have any ideas on what I'm doing wrong and how I could do it with ZF3 ?

这是我的module/User/config.module.config.php文件的简化版本

Here is a simplified version of my module/User/config.module.config.php file

namespace User;

use ...

return [
    'router' => [...],
    'controllers' => [...],
    'service_manager' => [
        'factories' => [
            Service\AuthenticationServiceFactory::class => InvokableFactory::class,
        ],
    ],
];

这是我的module/User/src/Service/AuthenticationServiceFactory.php文件

Here is my module/User/src/Service/AuthenticationServiceFactory.php file

namespace User\Service;

use Interop\Container\ContainerInterface;
use Zend\Authentication\AuthenticationService;
use Zend\ServiceManager\Factory\FactoryInterface;
use Zend\Db\Adapter\Adapter as DbAdapter;
use Zend\Authentication\Adapter\DbTable\CredentialTreatmentAdapter as AuthAdapter;
use Zend\Authentication\Storage\Session as Storage;

class AuthenticationServiceFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $controllerPluginManager = $container;
        $serviceManager = $controllerPluginManager->get('ServiceManager');
        $config = $serviceManager->get('configuration');

        $dbAdapter = new DbAdapter($config['db']); // Mysqli driver working in other modules

        $authAdapter = new AuthAdapter($dbAdapter);
        $authAdapter->setTableName('user')->setIdentityColumn('username')->setCredentialColumn('password');

        $storage = new Storage();

        return new AuthenticationService($storage, $authAdapter);
    }
}

这是我的module/User/src/Module.php文件

Here is my module/User/src/Module.php file

namespace User\Service;

use Zend\Mvc\MvcEvent;
use Zend\Authentication\Adapter\DbTable\CredentialTreatmentAdapter;

class Module
{
    public function getConfig()
    {
        return include __DIR__ . '/../config/module.config.php';
    }

    public function onBootstrap(MvcEvent $e)
    {
        $services = $e->getApplication()->getServiceManager();
        $auth = $services->get(AuthenticationServiceFactory::class);

        // Returns Fatal error: Call to undefined method Zend\Authentication\AuthenticationServiceFactory::setIdentity()
        // $auth is an AuthenticationServiceFactory object and not the AuthenticationService returned by its __invoke() function  
        $this->authAdapter->setIdentity('dummy_user_name');
        $this->authAdapter->setCredential('dummy_password');
        print_r($this->authAdapter->authenticate());
    }
}

有什么想法吗?

推荐答案

和往常一样,当我自己找到答案时,我会将其张贴在此处,以防它可能对某人有所帮助.

As usual, when I find the answer by myself, I post it here en case it may help someone.

module/User/config.module.php

module/User/config.module.php

namespace User;

use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
use Zend\ServiceManager\Factory\InvokableFactory;

return [
    'router' => [...],
    'controllers' => [...],
    'service_manager' => [
        'factories' => [
            'auth-service' => Service\AuthenticationServiceFactory::class,
        ],
    ],
];

module/User/src/Service/AuthenticationServiceFactory.php

module/User/src/Service/AuthenticationServiceFactory.php

namespace User\Service;

use Interop\Container\ContainerInterface;
use Zend\Authentication\AuthenticationService;
use Zend\ServiceManager\Factory\FactoryInterface;
use Zend\Db\Adapter\Adapter as DbAdapter;
use Zend\Authentication\Adapter\DbTable\CredentialTreatmentAdapter as AuthAdapter;
use Zend\Authentication\Storage\Session as Storage;

class AuthenticationServiceFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        // Get data from config files.
        $controllerPluginManager = $container;
        $serviceManager = $controllerPluginManager->get('ServiceManager');
        $config = $serviceManager->get('configuration');
        // or we can simplify these 3 lines using the following
        //$config = $container->get('configuration');

        // Configure DbAdapter with set-up information from config files.
        $dbAdapter = new DbAdapter($config['db']); // Mysqli driver working in other modules

        // Configure AuthAdapter with DbAdapter.
        // See https://docs.zendframework.com/zend-authentication/adapter/dbtable/credential-treatment/
        $authAdapter = new AuthAdapter($dbAdapter);
        $authAdapter->setTableName('user')->setIdentityColumn('username')->setCredentialColumn('password');

        // Configure session storage.
        $storage = new Storage();

        // Return AuthenticationService.
        return new AuthenticationService($storage, $authAdapter);
    }
}

module/User/src/Module.php

module/User/src/Module.php

namespace User\Service;

use Zend\Mvc\MvcEvent;
use Zend\Authentication\Adapter\DbTable\CredentialTreatmentAdapter;

class Module
{
    public function getConfig()
    {
        return include __DIR__ . '/../config/module.config.php';
    }

    public function onBootstrap(MvcEvent $e)
    {
        // Get the service manager.
        $services = $e->getApplication()->getServiceManager();

        // Set event to retrieve user's identity for every request.
        $eventManager = $e->getApplication()->getEventManager();
        $eventManager->attach(MvcEvent::EVENT_ROUTE, array($this, 'protectPage'), -100);
    }

    public function protectPage(MvcEvent $event)
    {
        $match = $event->getRouteMatch();
        if (! $match) {
            // We cannot do anything without a resolved route.
            return;
        }

        // Get AuthenticationService and do the verification.
        $services = $event->getApplication()->getServiceManager();
        $authService = $services->get('auth-service');

        // If user does not have an identity yet.
        if (! $authService->hasIdentity()) {
            // Do what you want like routing to login page...
        }
    }
}

我的问题是,不应在此处设置用户的身份和凭证,而应在其他地方的login()功能中进行设置.在Module Class中,我们只需要检查身份即可.

My problem was that setting user's identity and credential was not supposed to be done here but rather in a login() function somewhere else. In the Module Class we just need to check the identity.

这篇关于ZF3 MVC Zend \身份验证即服务工厂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆