簡體   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