繁体   English   中英

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

[英]Auth Adapter in Laminas Framework

最近,我将 Zend Framework(或 Laminas)的版本从 2.x 版升级到 3.x 版,但在验证用户时遇到了问题。 我的代码在 Zend Framework 2 上运行良好,在搜索谷歌并尝试自己解决问题后,我认为我已经缩小了范围,但我只需要一点帮助。

无论如何,这是我的代码

模块.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;
            }, 
    ];
}

我不知道这是否也需要,但这是我的 module.config.php 文件

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

当我尝试运行登录代码时,我在 controller 文件的第 76 行遇到了关于 Auth Adapter 的错误,如下所示

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

我认为错误是实际服务LoginAuthServiceGateway,但我不完全确定。

哦,如果这也有帮助,这里是异常消息的屏幕截图

在此处输入图像描述

任何帮助将不胜感激,如果需要更多信息,我会尽力提供更多

谢谢!

这是我的 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');
}

}

我认为问题在于您要声明Controller\LoginController两次。

第一次,您在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
                    )
                );
            },
        ),
    ];
}

但是您也在module.config.php中声明它:

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

但是,我不确定最后一个配置是否有效。 LoginController构造函数需要三个参数,并且都不是LoginAuthServiceGateway

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

因此, ReflectionBasedAbstractFactory将创建一个没有适配器的AuthenticationService的“简单”实例。这将解释为什么会出现该错误( $this->auth_service->getAdapter()返回 null 值)

您有两个选择,在您的配置中只保留一个LoginController声明,并进行适当的更正。

第一个选项:(我建议的那个)删除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);
            },
        ),
    ];
}

第一个选项:仅使用ReflectionBasedAbstractFactory 删除module.config.php中的声明并修改Module.php

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

并修复LoginController构造函数:

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

据我所知,错误可能在这一行:

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

它应该是

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

反而。

暂无
暂无

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

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