When trying to enter a site gives me an error of missing route in cakephp 4.2.4

I have a site where I want to login with user and password, the controller is Users and the action is login, the view is called login.php, but gives me this error:


The code of login.php is this:

</div>
<br/>
<div class='row'>
    <div class='col-md-3 hidden-sm hidden-xs'>
   </div>
    <div class='col-md-4 col-md-offset-1 col-xs-8 col-xs-offset-2 box-challenge well'>
    <div class='box-createproposal'>
<?php echo $this->Flash->render('auth'); ?>
<?php echo $this->Form->create('User'); ?>
    <fieldset>
        <legend>
            Ingresá tu nombre de usuario y contraseña
        </legend>
        <?php echo $this->Form->input('username',array('class'=>'form-control'));
        echo $this->Form->input('password',array('class'=>'form-control'));
    ?>   
    </fieldset>
    <br/>
<center>
       <div class='pull-center'>
    <?php
       echo $this->Form->submit(
        'INGRESAR ', 
        array('id' => 'btnCreateUser','class' => 'btn btn-primary btn-lg', 'title' => 'INGRESAR')
    );
        ?>
    </div>
</center>
</div>
<br/>
</div>

What should I do to solve this issue?

1st check login action is called or not from controller.
Try pj(‘test’);exit(); in login action

Your stack trace shows that this error is coming from the AuthenticationMiddleware service configuration. Look there to find why the URL you’re trying to use for logins isn’t valid.

I don’t know what to look, I am new to this version of cakephp.
This is the code of UsersController.php:

<?php
namespace App\Controller;

use Cake\Controller\Controller;
use Cake\Event;

class UsersController extends AppController {
        
    public $helpers = ['Html', 'Form'];
    var $uses = ['User'];

	public function beforeFilter(EventInterface $event)
	{
		parent::beforeFilter($event);

		$this->Authentication->allowUnauthenticated(['login']);
	}
	
    public function login() {
		if ($this->request->is('post')) {
        //Tomo el usuario a traves del Username, para validar si esta activo, sin loguearme
            $username = $this->request->data['User']['username'];
            $user = $this->User->find('first', ['conditions' => ['User.username' => $username]]);
            if($user != null && $user['User']['active'] != true){
                    $this->Session->setFlash(__('Usuario pendiente de activación!'),'msg_danger');
            }else if ($this->Auth->login()) {           
                return $this->redirect(['controller' => 'home', 'action' => 'index']);
            }else{
                $this->Session->setFlash(__('Nombre de usuario y/o contraseña incorrectos'),'msg_danger');
            }
        }
    }

    public function logout() {
        $this->Auth->logout();
        return $this->redirect(['controller' => 'home', 'action' => 'index']);
    }    
}
?>

Again, look at the stack trace. It tells you exactly where the error is happening. It’s nowhere near your UsersController.

Yes, I am watching at the getAuthenticationService method in the Application class but don’t see no error, this method has this code:

	public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
	{
		$service = new AuthenticationService();

		// Define where users should be redirected to when they are not authenticated
		$service->setConfig([
			'unauthenticatedRedirect' => Router::url([
					'prefix' => false,
					'plugin' => null,
					'controller' => 'Users',
					'action' => 'login',
			]),
			'queryParam' => 'redirect',
		]);

		$fields = [
			IdentifierInterface::CREDENTIAL_USERNAME => 'email',
			IdentifierInterface::CREDENTIAL_PASSWORD => 'password'
		];
		// 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',
			]),
		]);

		// Load identifiers
		$service->loadIdentifier('Authentication.Password', compact('fields'));

		return $service;
	}

Can you tell where the error is?

The URL that you are providing here for the “unauthenticatedRedirect” exactly matches what your error message says cannot be matched to any route. So, either this URL is wrong, or your routes are.

In what folders should I put the controllers and templates?
Maybe that’s the problem, I a m putting them in the wrong folders.
Or maybe the error is in my AppController class, this is the code for it:

<?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     0.2.9
 * @license   https://opensource.org/licenses/mit-license.php MIT License
 */
namespace App\Controller;

use Cake\Controller\Controller;

/**
 * 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');
		$this->loadComponent('Auth',[
            'loginRedirect' => [
                'controller' => 'home',
                'action' => 'index'
            ],
            'logoutRedirect' => [
                'controller' => 'home',
                'action' => 'index'
            ],
            'authenticate' => [
                'Form' => [
                    'passwordHasher' => 'Blowfish'
                ]
            ]
        ]);
		$this->loadComponent('Authorization.Authorization');

        /*
         * 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');
    }
}

It’s pretty hard to help you here. You’re not even sure what folders to put files in? And it seems like you’re mixing and matching things from the old authentication system ($this->Auth) and the new ($this->Authentication)? And the $helpers and $uses were eliminated quite some time ago. I’m guessing that you’ve just jumped straight in by copying things from random tutorials or questions on the internet without understanding the how or why of any of it, or even getting the version right, and it’s causing you problems.

I’d go back to basics. Start with the official v4 tutorial. (It’s not perfect, but you should learn the correct file and folder structure, and how to add routes, among other things.) Then add the new authentication plugin, following the directions that come with it. (If anything mentions $this->Auth, that’s not it.) That should at least put you in a place where you can ask a meaningful question when you run into a problem, as compared to this one where it seems that there’s quite a lot to be undone before any actual help can really come.

I figured it out, it says to create a matching route in config/routes.php, I created it with

$builder->connect('/users/login', ['controller' => 'Users', 'action' => 'login']);

but it still gives me the error.
Please help me to solve this issue.

Still gives the exact same error, or still gives some error? As I said, you’re trying to mix and match authentication from different sources, which is likely to crash it, and maybe there’s other things like that lurking in whatever you’ve done.

To confirm that the route is set up correctly, you should be able to run bin/cake routes.

It still gives me the same error, but when I run bin/cake routes it shows me this:


And I changed everything to the new Authentication plugin.

So, I’m no expert on routing, but it seems super weird to me that the one for /users/login has '0': 'login' in it. And it feels like that could very easily be what’s causing it to fail to match. Check that you’re not accidentally defining that route somewhere else with different parameters?

The 0 in the route is the parameter to select the view to use, I deleted it because the view is the same name as the action in the controller, but it keeps giving me the same error, maybe I’m missing one step before or after connecting the route, if you know please tell me what it is.

Yes, by default, the view will be the same as the action name, so generally no need to specify that.

So, when you run bin/cake routes now, the route for /users/login is {"action":"login","controller":"Users","plugin":null}? And yet it’s giving you an error reading “A route matching “array ( ‘prefix’ => false, ‘plugin’ => NULL, ‘controller’ => ‘Users’, ‘action’ => ‘login’, ‘_ext’ => NULL )” could not be found.” when you try to load pages?

Yes, that’s right.
Can you help me with that issue please?

No, I have no idea at this point why that would be happening. Hopefully, somebody that knows routing better will be able to assist.

Can someone who knows about routing help me with this issue please?
I am stuck with this problem.

I repaired the error, the problem was in the middleware method of Application class, I was calling

add(new AuthenticationMiddleware($this))

and

add(new AuthorizationMiddleware($this))

before

 add(new RoutingMiddleware($this))

when I put them below the RoutingMiddleware it worked fine.
Now I have another question, when I want to login with the username and password stored in the users table it gives me the Invalid username or password error, in the getAuthenticationService method I put this:

$fields = [
    IdentifierInterface::CREDENTIAL_USERNAME => 'username',
    IdentifierInterface::CREDENTIAL_PASSWORD => 'password'
];
		$service->loadAuthenticator('Authentication.Session');
		$service->loadAuthenticator('Authentication.Form', [
			'fields' => $fields,
			'loginUrl' => Router::url([
				'prefix' => false,
				'plugin' => null,
				'controller' => 'Users',
				'action' => 'login',
			]),
		]);

And this is the code for login action:

	public function login()
	{
		$this->Authorization->skipAuthorization();
		$result = $this->Authentication->getResult();
		// If the user is logged in send them away.
		if ($result->isValid()) {
			$target = $this->Authentication->getLoginRedirect() ?? '/home';
			return $this->redirect($target);
		}
		if ($this->request->is('post') && !$result->isValid()) {
			$this->Flash->error('Invalid username or password');
		}
	}

Am I missing something to make it work the login?

The login is working fine, but when I want to redirect to the index action it gives me the error “The request to / did not apply any authorization checks”.
How can I solve this issue?