简体   繁体   English

Laminas 框架中的身份验证适配器

[英]Auth Adapter in Laminas Framework

Recently I've upgraded versions of Zend Framework (or Laminas) from version 2.x to 3.x and I've running into a issue with authenticating users.最近,我将 Zend Framework(或 Laminas)的版本从 2.x 版升级到 3.x 版,但在验证用户时遇到了问题。 My code worked fine with Zend Framework 2 and after searching google and trying to solve the issue on my own, I've think I've narrowed it down but I just need a little help.我的代码在 Zend Framework 2 上运行良好,在搜索谷歌并尝试自己解决问题后,我认为我已经缩小了范围,但我只需要一点帮助。

Anyways, here is my code无论如何,这是我的代码

Module.php -模块.php -

public function getControllerConfig()
{
    return [
        'factories' => array(
            Controller\RegisterController::class => function ($container) {
                return new Controller\RegisterController(
                    $container->get(RegisterModel::class)
                );
            },
            
            Controller\VerifyController::class => function ($container) {
                return new Controller\VerifyController(
                    $container->get(VerifyModel::class)
                );
            },
            
            Controller\LoginController::class => function ($container) {
                return new Controller\LoginController(
                    $container->get(LoginModel::class, LoginAuthServiceGateway::class, LoginAuthStorage::class)
                );
            },
        ),
    ];
}

public function getServiceConfig() 
{ 
    return [ 
        'factories' => 
             LoginAuthServiceGateway::class => function($sm) {
                $db_adapter = $sm->get(Adapter::class);
                $auth_adapter = new DbTableAuthAdapter($db_adapter, 'users', 'username', 'password');
                
                $auth_service = new AuthenticationService();
                $auth_service->setAdapter($auth_adapter);
                $auth_service->setStorage($sm->get(LoginAuthStorage::class));
                
                return $auth_service;
            }, 
    ];
}

I don't know if this is needed as well but here is my module.config.php file我不知道这是否也需要,但这是我的 module.config.php 文件

'controllers' => [
    'factories' => [
        Controller\LoginController::class => ReflectionBasedAbstractFactory::class,
    ],
],

When I try to run the login code, I'm faced with an error regarding the Auth Adapter, at line 76 in my controller file which is as follows当我尝试运行登录代码时,我在 controller 文件的第 76 行遇到了关于 Auth Adapter 的错误,如下所示

 $this->auth_service->getAdapter()
    ->setIdentity($login->username)
    ->setCredential($this->model->handleLogin()->verifyCredentials($login)['pass']);

I think the error the actual service LoginAuthServiceGateway, but I am not entirely sure.我认为错误是实际服务LoginAuthServiceGateway,但我不完全确定。

Oh, if this helps too here is an screenshot of the exception message哦,如果这也有帮助,这里是异常消息的屏幕截图

在此处输入图像描述

Any help would be appreciated, and if more information is needed I'll try to give more任何帮助将不胜感激,如果需要更多信息,我会尽力提供更多

Thanks!谢谢!

Here is the code inside of my controller:这是我的 controller 里面的代码:

use Application\Model\Storage\LoginAuthStorage;
use Laminas\Authentication\AuthenticationService;
use Laminas\Mvc\Controller\AbstractActionController;

use Laminas\View\Model\ViewModel;

use Application\Model\LoginModel;

use Application\Form\LoginForm;
use Application\Model\Filters\Login;

    class LoginController extends AbstractActionController
    {
          public $auth_service;
          public $storage;

          private $model;

          public function __construct(LoginModel $model, AuthenticationService $auth_service, LoginAuthStorage $storage)
          {
              $this->model = $model;
              $this->auth_service = $auth_service;
              $this->storage = $storage;
          }

          public function indexAction()
          {
             if ($this->auth_service->hasIdentity()) {
                 return $this->redirect()->toRoute('home/user');
             }
    
             $form = new LoginForm();
    
             return new ViewModel(array('form' => $form));
          }


public function authAction()
{
    $form = new LoginForm();
    
    $request = $this->getRequest();
    
    if ($request->isPost()) {
        $login = new Login();
        
        $form->setInputFilter($login->getInputFilter());
        $form->setData($request->getPost());
        
        if ($form->isValid()) {
            $login->exchangeArray($form->getData());
            
            try {
                if (!$this->model->handleLogin()->verifyCredentials($login)) {
                    $this->flashMessenger()->addErrorMessage('Invalid username and/or password');
                }
                
                if (!$this->model->handleLogin()->checkSession(array('username' => $login->username))) {
                    $this->flashMessenger()->addErrorMessage('A session is already active with that username.');
                }
            } catch (\Exception $e) {
                return $this->redirect()->toRoute('home/login', array('action' => 'failure'));
            }
            
           // var_dump($this->auth_service);
            
            $this->auth_service->getAdapter()
            ->setIdentity($login->username)
            ->setCredential($this->model->handleLogin()->verifyCredentials($login)['pass']);
            
            $result = $this->auth_service->authenticate();
            
            foreach ($result->getMessages() as $message) {
                $this->flashMessenger()->addMessage($message);
            }
            
            if ($result->isValid()) {
                if ($login->remember_me == 1) {
                    try {
                        $this->storage->rememberUser(1);
                        $this->auth_service->getStorage()->write($login->username);
                        
                        $this->model->handleLogin()->insertSession(array('username' => $login->username,
                            'password' => $this->model->handleLogin()->verifyCredentials($login)['pass'], 'session_id' => session_id()));
                    } catch (\Exception $e) {
                        return $this->redirect()->toRoute('home/login', array('action' => 'failure'));
                    }
                } else if ($login->remember_me == 0) {
                    try {
                        $this->storage->rememberUser(0);
                        $this->auth_service->getStorage()->write($login->username);
                        
                        $this->model->handleLogin()->insertSession(array('username' => $login->username,
                            'password' => $this->model->handleLogin()->verifyCredentials($login)['pass'], 'session_id' => session_id()));
                    } catch (\Exception $e) {
                        return $this->redirect()->toRoute('home/login', array('action' => 'failure'));
                    }
                }
                
                return $this->redirect()->toRoute('home/user');
            } else {
                foreach ($result->getMessages() as $message) {
                    $this->flashMessenger()->addErrorMessage($message);
                }
                return $this->redirect()->toRoute('home/login', array('action' => 'failure'));
            }
        } else {
            $this->flashMessenger()->addErrorMessage("Invalid form submitted, most likely due to invalid credentials or empty values.");
            
            return $this->redirect()->toRoute('home/login', array('action' => 'failure'));
        }
    }
}


public function failureAction()
{
    $this->layout('layout/failure');
}

} }

I think the problem is that you are declaring Controller\LoginController twice.我认为问题在于您要声明Controller\LoginController两次。

The first time, you declare it in your Module.php第一次,您在Module.php中声明它

public function getControllerConfig()
{
    return [
        'factories' => array(
            Controller\LoginController::class => function ($container) {
                return new Controller\LoginController(
                    $container->get(
                        LoginModel::class,
                        LoginAuthServiceGateway::class, 
                        LoginAuthStorage::class
                    )
                );
            },
        ),
    ];
}

But you also declare it in module.config.php :但是您也在module.config.php中声明它:

'controllers' => [
    'factories' => [
        Controller\LoginController::class => ReflectionBasedAbstractFactory::class,
    ],
]

However, I'm not sure this last configuration will work.但是,我不确定最后一个配置是否有效。 LoginController constructor requires three parameters, and none of them is LoginAuthServiceGateway . LoginController构造函数需要三个参数,并且都不是LoginAuthServiceGateway

public function __construct(LoginModel $model, AuthenticationService $auth_service, LoginAuthStorage $storage)
{
    $this->model = $model;
    $this->auth_service = $auth_service;
    $this->storage = $storage;
}

Therefore, ReflectionBasedAbstractFactory will create a "simple" instance of AuthenticationService , without an adapter.. and this will explain why you get that error ( $this->auth_service->getAdapter() returns a null value)因此, ReflectionBasedAbstractFactory将创建一个没有适配器的AuthenticationService的“简单”实例。这将解释为什么会出现该错误( $this->auth_service->getAdapter()返回 null 值)

You have two options, keeping only one declaration of LoginController in your configs, with proper corrections.您有两个选择,在您的配置中只保留一个LoginController声明,并进行适当的更正。

First option : (the one I suggest) Remove the declaration in module.config.php and modify Module.php as follows:第一个选项:(我建议的那个)删除module.config.php中的声明并修改Module.php如下:

public function getControllerConfig()
{
    return [
        'factories' => array(
            Controller\LoginController::class => function ($container) {
                $loginModel = $container->get(LoginModel::class);
                $authService = $container->get(LoginAuthServiceGateway::class);
                $authStorage = $container->get(LoginAuthStorage::class);

                return new Controller\LoginController($loginModel, $authService, $authStorage);
            },
        ),
    ];
}

First option: use only ReflectionBasedAbstractFactory .第一个选项:仅使用ReflectionBasedAbstractFactory Remove the declaration in module.config.php and modify Module.php :删除module.config.php中的声明并修改Module.php

public function getControllerConfig()
{
    return [
        'factories' => array(
            Controller\LoginController::class => ReflectionBasedAbstractFactory::class
        ),
    ];
}

AND fix LoginController constructor:并修复LoginController构造函数:

public function __construct(LoginModel $model, LoginAuthServiceGateway $auth_service, LoginAuthStorage $storage)
{
    $this->model = $model;
    $this->auth_service = $auth_service;
    $this->storage = $storage;
}

From what I can see, the error is probably at this line:据我所知,错误可能在这一行:

$container->get(LoginModel::class, LoginAuthServiceGateway::class, LoginAuthStorage::class)

It should be它应该是

$container->get(LoginModel::class),
$container->get(LoginAuthServiceGateway::class),
$container->get(LoginAuthStorage::class)

instead.反而。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM