How to use a separate authentication or Application.php

Hi. Forgive my poor english please.

My site has frontend, backend and api like:
http://www.example.com
http://www.example.com/admin
http://www.example.com/api

// config/routes.php
Router::prefix('admin', function (RouteBuilder $routes) {
});
Router::prefix('api', function (RouteBuilder $routes) {
});
// directory structure
src/
    Application.php
    Controller/
        AppController.php
        Admin/
            AppController.php
        Api/
            AppController.php

I am using cakephp/authentication plugin for authentication.

        // Add the authentication middleware
        $authentication = new AuthenticationMiddleware($this, [
            'unauthenticatedRedirect' => '/login',
            'queryParam' => 'redirect',
        ]);
        // Add the middleware to the middleware queue
        $middlewareQueue->add($authentication);
.....

        $fields = [
                'username' => 'id',
                'password' => 'password'
        ];
        $service->loadIdentifier('Authentication.Password', [
            'fields' => $fields,
            'resolver' => [
                'className' => 'Authentication.Orm',
                'userModel' => 'Customers' // may be Admins for '/admin'
            ]
        ]);
        $service->loadAuthenticator('Authentication.Session');

But I have to use different Authenticators and Identifiers for different router. For example, frontend uses CustomersTable, backend uses UsersTable, api for APP use TokenAuthenticator…

What’s the best way to do?

I’m now making another AdminApplication.php for ‘/admin’, and modify index.php like this:

// webroot/index.php
if (stripos($_SERVER['REQUEST_URI'], '/admin') === 0) {
    $server = new Server(new AdminApplication(dirname(__DIR__) . '/config'));
} else {
    $server = new Server(new Application(dirname(__DIR__) . '/config'));
}

But I don’t think it’s a good way…

Please, help me.

Just pass a different userModel to the resolver configuration, depending on the URL?

Or, more commonly, combine the two user tables together and include a “role” column or the like to differentiate them.

This is my approach to do this :

in config/routes.php

$routes->prefix(
    'Backend',
    ['path' => '/gestion', '_namePrefix' => 'backend:'],
    function (RouteBuilder $builder) {
        $authenticationService = new AuthenticationService();
        $fields = [
            IdentifierInterface::CREDENTIAL_USERNAME => 'email',
            IdentifierInterface::CREDENTIAL_PASSWORD => 'password',
        ];
        $authenticationService->loadAuthenticator(SessionAuthenticator::class);
        $authenticationService->loadAuthenticator(FormAuthenticator::class, [
            'fields' => $fields,
            'loginUrl' => ['_name' => 'backend:auth:login'],
        ]);

        $builder->registerMiddleware('authentication', new AuthenticationMiddleware($authenticationService));
        $builder->applyMiddleware('authentication');

In your Prefix App Controller:

    public function initialize(): void
    {
        parent::initialize();

        $service = $this->request->getAttribute('authentication');
        $service->setConfig([
            'unauthenticatedRedirect' => Router::url(['_name' => 'backend:auth:login']),
            'queryParam' => 'r',
        ]);

        $this->loadComponent('Authentication.Authentication');
    }

You can use one AuthenticationService by prefix, configured as you want.