CakePHP : Utiliser un service d’authentification différent suivant le prefix
La base
Dans une application CakePHP, vous pouvez avoir une partie “front” qui ne nécessite pas d’authentification, contrairement à la partie “backend”.
Le “backend” peut être configuré à l’aide de prefix de route comme documenté ici
Le plus simple est de configuré le plugin cakephp/authentication dans votre src/Application.php
en ajoutant le plugin, le middleware et la configuration du service dans Application::getAuthenticationService()
.
Ensuite, il suffit d’ajouter, dans votre App\Controller\BackendController::initialize()
:
public function initialize(): void
{
parent::initialize();
$this->loadComponent('Authentication.Authentication');
]
Et le tour est joué.
Plus de complexité
(short english explanation on cakephp forum)
On peut être amené à avoir une partie du site qui utilise un FormAuthenticator
alors qu’une autre partie va utiliser un HttpDigest
ou Token
. Dans ce cas, voici une solution, un peu plus complexe mais qui est aussi plus souple.
Dans le fichier 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,
'urlChecker' => '\Authentication\UrlChecker\CakeRouterUrlChecker',
'loginUrl' => ['_name' => 'backend:auth:login'],
]);
$authenticationService->loadIdentifier(PasswordIdentifier::class, [
'fields' => $fields,
]);
$builder->registerMiddleware('authentication', new AuthenticationMiddleware($authenticationService));
$builder->applyMiddleware('authentication');
Dans le fichier Application::bootstrap()
:
$this->addPlugin('Authentication');
Et ensuite dans le Controller
de votre prefix :
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');
}
Désormais, ce prefix va utiliser le service d’Authentification que vous avez configuré dans votre fichier de routes. Et vous pouvez en configurer 1 par prefix, sans limitation.