Плагин аутентификации CakePHP превращает идентификатор в __PHP_Неполный_объект класса

#php #cakephp

#php #cakephp

Вопрос:

Я протестировал приведенные ниже образцы с небольшими изменениями на Application.php в CakePHP3.8 и плагине аутентификации 1.4.2 также Cake4.x и плагине аутентификации 2.x.

Оба превращают объект идентификации в __PHP_Неполный_объект класса

Ниже приведен Application.php файл, который я использую для тестирования плагина аутентификации

 <?php
declare(strict_types=1);

/**
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 * @link      https://cakephp.org CakePHP(tm) Project
 * @since     3.3.0
 * @license   https://opensource.org/licenses/mit-license.php MIT License
 */
namespace App;

use CakeCoreConfigure;
use CakeCoreExceptionMissingPluginException;
use CakeErrorMiddlewareErrorHandlerMiddleware;
use CakeHttpBaseApplication;
use CakeHttpMiddlewareBodyParserMiddleware;
//use CakeHttpMiddlewareCsrfProtectionMiddleware;
use CakeHttpMiddlewareQueue;
use CakeRoutingMiddlewareAssetMiddleware;
use CakeRoutingMiddlewareRoutingMiddleware;

use AuthenticationAuthenticationService;
use AuthenticationAuthenticationServiceInterface;
use AuthenticationAuthenticationServiceProviderInterface;
use AuthenticationIdentifierIdentifierInterface;
use AuthenticationMiddlewareAuthenticationMiddleware;
use CakeRoutingRouter;
use PsrHttpMessageServerRequestInterface;

/**
 * Application setup class.
 *
 * This defines the bootstrapping logic and middleware layers you
 * want to use in your application.
 */
class Application extends BaseApplication implements AuthenticationServiceProviderInterface
{
    /**
     * Load all the application configuration and bootstrap logic.
     *
     * @return void
     */
    public function bootstrap(): void
    {
        // Call parent to load bootstrap from files.
        parent::bootstrap();

        if (PHP_SAPI === 'cli') {
            $this->bootstrapCli();
        }

        /*
         * Only try to load DebugKit in development mode
         * Debug Kit should not be installed on a production system
         */
        if (Configure::read('debug')) {
            $this->addPlugin('DebugKit');
        }

        // Load more plugins here
        $this->addPlugin('Authentication');
    }

    /**
     * Setup the middleware queue your application will use.
     *
     * @param CakeHttpMiddlewareQueue $middlewareQueue The middleware queue to setup.
     * @return CakeHttpMiddlewareQueue The updated middleware queue.
     */
    public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
    {
        $middlewareQueue
            // Catch any exceptions in the lower layers,
            // and make an error page/response
            ->add(new ErrorHandlerMiddleware(Configure::read('Error')))

            // Handle plugin/theme assets like CakePHP normally does.
            ->add(new AssetMiddleware([
                'cacheTime' => Configure::read('Asset.cacheTime'),
            ]))

            // Add routing middleware.
            // If you have a large number of routes connected, turning on routes
            // caching in production could improve performance. For that when
            // creating the middleware instance specify the cache config name by
            // using it's second constructor argument:
            // `new RoutingMiddleware($this, '_cake_routes_')`
            ->add(new RoutingMiddleware($this))

            // Parse various types of encoded request bodies so that they are
            // available as array through $request->getData()
            // https://book.cakephp.org/4/en/controllers/middleware.html#body-parser-middleware
            ->add(new BodyParserMiddleware())

            // Cross Site Request Forgery (CSRF) Protection Middleware
            // https://book.cakephp.org/4/en/controllers/middleware.html#cross-site-request-forgery-csrf-middleware
            /*->add(new CsrfProtectionMiddleware([
                'httponly' => true,
            ]))*/
            ->add(new AuthenticationMiddleware($this));
        return $middlewareQueue;
    }

    /**
     * Bootstrapping for CLI application.
     *
     * That is when running commands.
     *
     * @return void
     */
    protected function bootstrapCli(): void
    {
        try {
            $this->addPlugin('Bake');
        } catch (MissingPluginException $e) {
            // Do not halt if the plugin is missing
        }

        $this->addPlugin('Migrations');

        // Load more plugins here
    }

    /**
     * Returns a service provider instance.
     *
     * @param PsrHttpMessageServerRequestInterface $request Request
     * @return AuthenticationAuthenticationServiceInterface
     */
    public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
    {
        $service = new AuthenticationService();

        $fields = [
            IdentifierInterface::CREDENTIAL_USERNAME => 'email',
            IdentifierInterface::CREDENTIAL_PASSWORD => 'password'
        ];

        // Load identifiers
        $service->loadIdentifier('Authentication.Password', [
            'resolver' => [
                'className' => 'Authentication.Orm',
                'userModel' => 'Users',
            ],
            'fields'    =>  $fields
        ]);
        // Load the authenticators. Session should be first.
        $service->loadAuthenticator('Authentication.Session');
        $service->loadAuthenticator('Authentication.Form', [
            'fields' => $fields,
            'loginUrl' => Router::url([
                'prefix' => false,
                'plugin' => null,
                'controller' => 'Users',
                'action' => 'login',
            ]),
        ]);

        return $service;
    }
}
 

и в AppController.php

 <?php
namespace AppController;

use CakeControllerController;

/**
 * Application Controller
 *
 * Add your application-wide methods in the class below, your controllers
 * will inherit them.
 *
 * @link https://book.cakephp.org/4/en/controllers.html#the-app-controller
 */
class AppController extends Controller
{
    /**
     * Initialization hook method.
     *
     * Use this method to add common initialization code like loading components.
     *
     * e.g. `$this->loadComponent('FormProtection');`
     *
     * @return void
     */
    public function initialize(): void
    {
        parent::initialize();

        $this->loadComponent('RequestHandler');
        $this->loadComponent('Flash');

        /*
         * Enable the following component for recommended CakePHP form protection settings.
         * see https://book.cakephp.org/4/en/controllers/components/form-protection.html
         */
        //$this->loadComponent('FormProtection');
        $this->loadComponent('Authentication.Authentication');
        $this->Authentication->allowUnauthenticated(['view', 'index']);
    }
}
 

в UsersController.php

  /**
     * Login
     * @return CakeHttpResponse
     */
    public function login() {
        $this->request->allowMethod(['get', 'post']);
        if ($this->request->is('post')) {
            $result = $this->Authentication->getResult();
            // regardless of POST or GET, redirect if user is logged in
            if ($result->isValid()) {
                $this->loadModel('Users');
                //testing purpose
                $data = $this->Users->get(1);
                $identity = new Identity($data);
                $this->Authentication->setIdentity($identity);
                // redirect to /articles after login success
                $redirect = $this->request->getQuery('redirect', [
                    'controller' => 'users',
                    'action' => 'list',
                ]);
                return $this->redirect($redirect);
            }
            // display error if user submitted and authentication failed
            if (!$result->isValid()) {
                $this->Flash->error(__('Invalid username or password'));
            }
        }
    }
 

Когда я печатаю информацию (т.Е.)

 pr($this->request->getAttribute('identity'));
 

Я получаю приведенный ниже ответ, который в любом случае не может быть проанализирован, чтобы получить данные аутентификации.

 AuthenticationIdentity Object
(
    [config] => Array
        (
            [fieldMap] => Array
                (
                    [id] => id
                )

        )

    [data] => ArrayObject Object
        (
            [storage:ArrayObject:private] => __PHP_Incomplete_Class Object
                (
                    [__PHP_Incomplete_Class_Name] => AuthenticationIdentity
                    [_defaultConfig:protected] => Array
                        (
                            [fieldMap] => Array
                                (
                                    [id] => id
                                )

                        )

                    [data:protected] => __PHP_Incomplete_Class Object
                        (
                            [__PHP_Incomplete_Class_Name] => AppModelEntityUser
                            [_accessible:protected] => Array
                                (
 

Кто-нибудь может подсказать мне, что здесь не так. Я застрял на этой работе более двух дней.

Заранее благодарю.

Комментарии:

1. Спасибо @Mitya за добавление тега CakePHP

2. Я нашел решение! Эта проблема возникает из-за версии PHP7.2. После обновления PHP7.4 эта проблема исчезла.