Problem about Laminas\Mvc\Plugin\Identity

I am working on the for a whole afternoon! Anybody can help me out?

I installed Laminas\Mvc\Plugin\Identity

my project/config/modules.config.php

return [
    'Laminas\Mvc\Plugin\FilePrg',
    'Laminas\Mvc\Plugin\FlashMessenger',
    'Laminas\Mvc\Plugin\Identity', // ====> here
    'Laminas\Mvc\Plugin\Prg',
    'Laminas\Session',
    'Laminas\Form',
    'Laminas\I18n',
    'Laminas\Log',
    'Laminas\InputFilter',
    'Laminas\Filter',
    'Laminas\Hydrator',
    'Laminas\Di',
    'Laminas\Db',
    'Laminas\Cache',
    'Laminas\Router',
    'Laminas\Validator',
    'Application',
];

module/Application/config/module.config.php

use Application\Service\AuthManager;
use Application\Service\Factory\AuthenticationServiceFactory;
use Application\Service\Factory\AuthManagerFactory;
use Application\Service\Factory\CommonRedisFactory;
use Laminas\Authentication\AuthenticationServiceInterface;
use Laminas\Mvc\Controller\LazyControllerAbstractFactory;
use Laminas\Router\Http\Literal;
use Laminas\Router\Http\Segment;
use Redis;

...

'service_manager' => [
        'factories' => [
            AuthenticationServiceInterface::class => AuthenticationServiceFactory::class, // ===> here
            AuthManager::class => AuthManagerFactory::class, //use in bootstrap
            Redis::class => CommonRedisFactory::class, //获取单例的redis连接
        ],
    ],

module/Application/src/Service/Factory/AuthenticationServiceFactory.php

use Interop\Container\ContainerInterface;
use Interop\Container\Exception\ContainerException;
use Laminas\Authentication\Adapter\DbTable\CredentialTreatmentAdapter;
use Laminas\Authentication\AuthenticationService;
use Laminas\Db\Adapter\AdapterInterface;
use Laminas\ServiceManager\Exception\ServiceNotCreatedException;
use Laminas\ServiceManager\Exception\ServiceNotFoundException;
use Laminas\ServiceManager\Factory\FactoryInterface;

class AuthenticationServiceFactory implements FactoryInterface
{

    public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null)
    {
        exit('6666'); //not print out, it seems not exute this part.
        $dbAdapter = $container->get(AdapterInterface::class);

        $authAdapter = new CredentialTreatmentAdapter(
            $dbAdapter,
            'user',
            'username',
            'passwd',
            'SHA1(CONCAT(?, salt)) AND valid=1',
        );

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

in my Controller action

use Application\Form\UserForm;
use Application\Model\BaseFuncModel;
use Application\Model\User;
use Application\Model\UserTable;
use Laminas\Authentication\Adapter\DbTable\CredentialTreatmentAdapter;
use Laminas\Authentication\AuthenticationService;
use Laminas\Form\FormElementManager;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Mvc\Plugin\Identity\Identity;
use Laminas\View\Model\ViewModel;

class IndexController extends AbstractActionController
{
    private $baseFuncModel;
    private $formElementManager;
    private $userTable;

    /** 依赖注入 */
    public function __construct(BaseFuncModel $baseFuncModel, FormElementManager $formElementManager, UserTable $userTable)
    {
        $this->baseFuncModel = $baseFuncModel;
        $this->formElementManager = $formElementManager;
        $this->userTable = $userTable;
    }

    public function loginAction()
    {
        $form = $this->formElementManager->get(UserForm::class);
        $request = $this->getRequest();

        if (!$request->isPost())
        {
            $vm = new ViewModel(['form' => $form]);
            $vm->setTerminal(true);
            return $vm;
        }

        $form->setValidationGroup('username','passwd','formhash');
        $form->setData($request->getPost());

        if (!$form->isValid())
        {
            $vm = new ViewModel(['form' => $form]);
            $vm->setTerminal(true);
            return $vm;
        }

        $user = new User();
        $user->exchangeArray($form->getData());

        /** @var AuthenticationService $authenticationService */
        $authenticationService = $this->plugin('identity')->getAuthenticationService();

        /** @var CredentialTreatmentAdapter $adapter */
        $adapter = $authenticationService->getAdapter();
        var_dump($adapter);exit; // ======================> Null!!!!
        $adapter->setIdentity($user->username)->setCredential($user->passwd);

        if ($authenticationService->authenticate()->isValid()) //授权成功!!
        {
            $storage = $authenticationService->getStorage();
            $result = $adapter->getResultRowObject(['id','username','realname','role','valid','addtime','uptime']);
            $member = $this->userTable->fetchRecord(['id' => $result->id]);
            var_dump($result);
            var_dump($member);
            exit;
            $storage->write($member);
        }
        else
        {
            exit('error!');
        }
    }

I strictly check over this Problem in using the Identity Helper - #5 by froschdesign
I am sure it is almost the same.

Besides, I deleted the module config cache many times.

You should remove the exit calls and use debugger, for example Xdebug with an IDE like PHPStorm. There you can follow the application process. You can check if the plugin sets the authentication service:

Deactivate the cache during development, it’s easier. :wink:

Hi Frank, thanks for your reply!

From the code you showed upside.
I register AuthenticationServiceInterface::class => AuthenticationServiceFactory::class,,

It should be working well.

I do know some debug methods through phpstorm IDE. It is not a big project and I am not going to spend too much time on making the debugging environment.

I didn’t expect I run in trouble with this

$authenticationService = $this->plugin('identity')->getAuthenticationService();

I didn’t this kind many times, totally out of my mind.

You have misunderstood me, you should check the factory for the identity plugin with a debugger.

I am trying to config a xdebug environment here, It is a little hard for me to reading a whole english version article. :joy:
My poor English.

I found I config the service_manager factories as following, it works.

'service_manager' => [
        'factories' => [
            AuthenticationService::class => AuthenticationServiceFactory::class, //it works after I added this line !!!!
            AuthenticationServiceInterface::class => AuthenticationServiceFactory::class, //it seems useless!!!
            AuthManager::class => AuthManagerFactory::class, //use in bootstrap
            Redis::class => CommonRedisFactory::class, //
        ],
    ],

My conclusion:
register AuthenticationServiceInterface::class this key, not work, useless. I don’t know why, because last time register this key work in another project in earlier time.

It’s not, because the factory is clear and it works.

You can check your application configuration if you use / overwrite Laminas\Authentication\AuthenticationServiceInterface:class or Laminas\Authentication\AuthenticationService::class in other places.

Hi Frank,

I checked over all the project by searching AuthenticationServiceInterface::class and AuthenticationService::class, no else setted but the service_manager factories I set.

it is so weird

Whatever, the problem solved, I won’t bother any further.