Router Middleware is giving error. AuthenticationMiddleware

//config/router.php

$routes->registerMiddleware('cookies', new EncryptedCookieMiddleware(['secrets', 'protected'], ''));
$routes->registerMiddleware('auth', new AuthenticationMiddleware());
$routes->registerMiddleware('csrf', new CsrfProtectionMiddleware());

here is AuthenticationMiddleware throw error. I do the same thing as explain in Cakephp Documentation:-

$routes->registerMiddleware('cookie', new EncryptedCookieMiddleware());
$routes->registerMiddleware('auth', new AuthenticationMiddleware());
$routes->registerMiddleware('csrf', new CsrfProtectionMiddleware());
$routes->middlewareGroup('web', ['cookie', 'auth', 'csrf']);

// Apply the group
$routes->applyMiddleware('web');

but it all give error so solve one by one but not AuthenticationMiddleware. so please help I got this error

Just like the error says you are missing the constructor parameter for new AuthenticationMiddleware();

try

$routes->registerMiddleware('auth', new AuthenticationMiddleware($this));

$this inside the config/routes.php is still the instance of your src/Application.php so this should fix your problem.

thanks @KevinPfeifer but i already try this one but result are still same on the screen even your code giving this error, let me show you here in image

can you please post your whole config/routes.php

you may be in a sub-function where your scope is not the same

//route.php

use Cake\Core\Configure;
use Cake\Routing\RouteBuilder;
use Cake\Routing\Route\DashedRoute;
use Cake\Http\Middleware\CsrfProtectionMiddleware;
use Cake\Http\Middleware\EncryptedCookieMiddleware;
use Authentication\Middleware\AuthenticationMiddleware;

return static function (RouteBuilder $routes) {
    $routes->setRouteClass(DashedRoute::class);
    $routes->registerMiddleware('cookies', new EncryptedCookieMiddleware(['secrets', 'protected'], ''));
    //$routes->registerMiddleware('auth', new AuthenticationMiddleware());
    $routes->middlewareGroup('web', ['cookies']);
    $routes->applyMiddleware('web');

    $routes->scope('/', function (RouteBuilder $builder) {
        /*
         * Here, we are connecting '/' (base path) to a controller called 'Pages',
         * its action called 'display', and we pass a param to select the view file
         * to use (in this case, templates/Pages/home.php)...
         */
        $builder->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);

        /*
         * ...and connect the rest of 'Pages' controller's URLs.
         */
        $builder->connect('/pages/*', 'Pages::display');

        /*
         * Connect catchall routes for all controllers.
         *
         * The `fallbacks` method is a shortcut for
         *
         * ```
         * $builder->connect('/{controller}', ['action' => 'index']);
         * $builder->connect('/{controller}/{action}/*', []);
         * ```
         *
         * You can remove these routes once you've connected the
         * routes you want in your application.
         */
        $builder->fallbacks();
    });

//application.php file

//middleware

    ->add(new AuthenticationMiddleware($this))
    ->add(new AuthorizationMiddleware($this, [
                'unauthorizedHandler' => [
                    'className' => CheckAccess::class,
                    'url' => [
                        'controller' => 'Users',
                        'action' => 'login',
                        'prefix' => false,
                        'plugin' => null
                    ],
                    'queryParam' => false,
                    'exceptions' => [
                        ForbiddenException::class
                    ]
                ]
            ]))

The main problem here is the static function https://github.com/cakephp/app/blob/4.x/config/routes.php#L27 which wraps all routes.

Technically you don’t need that static function so you could remove that and it should work fine. Its mainly there so your IDE gives you autocompletion for which methods are available but you could also achieve this by adding

/**
 * @var \Cake\Routing\RouteBuilder $routes
 */

at the top of your config/routes.php

Otherwise you would have to build the middleware instances outside of the static function and pass them through like so

$authMiddleware = new \Authentication\Middleware\AuthenticationMiddleware($this);

return static function (RouteBuilder $routes) use ($authMiddleware) {
    // rest of your routes
}

My app doesn’t have that static method in the config/routes.php - thats why I didn’t encounter that before.

thanks @KevinPfeifer your suggestion help me and it works

$authMiddleware = new \Authentication\Middleware\AuthenticationMiddleware($this);
return static function (RouteBuilder $routes) use ($authMiddleware) {
// rest of your routes
}

but the problem is that now when I call Api like this http://localhost:8765/api/v1/members/login.json with GET request I got in response whole HTML template, login page

but if I send POST request then i get user data in response but with GET, but its ok i do not want to get data with GET Request but how can i show Error instead html template into error… like {error:{
message : ‘get method not allowed’}} in response;

$routes->scope(‘/api/v1/’, function (RouteBuilder $routes) {
$routes->setExtensions([‘json’, ‘xml’]);
$routes->resources(‘Tests’);
$routes->resources(‘Authcheck’, [
‘map’ => [
‘login’ => [
‘action’ => ‘login’,
‘method’ => [‘post’],
‘path’ => ‘login’
]
]
]);
});

//controllder code :-

public function beforeFilter(\Cake\Event\EventInterface $event)
{
parent::beforeFilter($event);
// for all controllers in our application, make index and view
// actions public, skipping the authentication check
$this->Authentication->addUnauthenticatedActions([‘index’, ‘view’, ‘login’]);

    if (in_array($this->request->getParam('action'), ['index', 'view', 'login'])) {
        $this->Authorization->skipAuthorization();
    }
}

public function login()
{
/* if ($this->request->allowMethod([‘post’]) != true) {
throw new MethodNotAllowedException();
} */
$this->request->allowMethod([‘post’]);

    $user = ['user' => ['id' => 1, 'name' => $this->request->getData('name'), 'email' => $this->request->getData('email')], 'token' => md5('adssad')];
    $this->set(compact('user'));
    $this->viewBuilder()->setOption('serialzie', ['user']);
}

//application.php

$service->setConfig([
‘unauthenticatedRedirect’ => Router::url([‘prefix’ => false, ‘plugin’ => null, ‘controller’ => ‘Users’, ‘action’ => ‘login’]),
‘queryParam’ => ‘redirect’,
]);

        // Load the authenticators, you want session first
        $service->loadAuthenticator('Authentication.Session');
        // Configure form data check to pick email and password
        $service->loadAuthenticator('Authentication.Form', [
            'fields' => $fields,
            'loginUrl' => Router::url('/users/login'),
        ]);
        // Load identifiers, ensure we check email and password fields
        $service->loadIdentifier('Authentication.Password', compact('fields'));

You usually add

$this->request->allowMethod(['post']);

at the beginning of your controller method to trigger a MethodNotAllowedException

But you already have that so it should prevent non POST Requests to get through

Which then can be rendered into a JSON with a plugin like MixerAPI ExceptionRender - CakePHP RESTful API plugin

alternatively, you could also try just removing the static part of

return static function (RouteBuilder $routes) use ($authMiddleware) {
    // rest of your routes
}

and it should work as well

oh! yeah i already try this plugin but it has not installed… this plugin not fulfill requirement with this composer. Actually I have latest composer and this plugin is support lower version… but the magic is that now this plugin installed so thank again @KevinPfeifer you really fixed my issue i will try it latter and reply you if get any problem.

composer require mixerapi/mixerapi

this plugin give me error when i am installing it,