Les autorisations avec CakePHP 1.2
[ 07 août 2008 ]Creusons-un peu dans le composant 'Auth' pour créer rapidement un système d'autorisation d'accès pour notre site.
Par défaut, CakePHP s'attend à ce que les utilisateurs soient appelés 'users', nous suivons donc ces recommandations. La première chose à faire consiste donc à créer une table dans la base de données (ici MySQL). Notez que les champs 'username' et 'password' sont aussi ceux attendus par le système, ne le décevons pas sur ce point (même si bien entendu, ce comportement peut être altéré, nous verrons plus tard comment). Attention également à la taille du champ 'password' qui doit être assez grand pour contenir la version chiffrée du mot de passe. 'Auth' s'en charge automatiquement.
CREATE TABLE `users` ( `id` INT( 14 ) NOT NULL AUTO_INCREMENT PRIMARY KEY , `username` VARCHAR( 12 ) NOT NULL , `password` VARCHAR( 40 ) NOT NULL , `email` VARCHAR( 128 ) NOT NULL `created` DATETIME NOT NULL , ) ENGINE = MYISAM
Ensuite nous créons le modèle correspondant, dans app/models/user.php:
<?php
class User extends AppModel {
var $name = 'User';
var $components = array('Acl','Auth');
}
?>
Puis le contôleur dans app/controllers/users_controller.php qui doit contenir deux fonctions, login et logout
<?php
class UsersController extends AppController {
var $name = 'Users';
var $scaffold;
function login(){}
function logout(){}
}
?>
Par défaut, le système nous interdit l'accès à la gestion des utilisateurs, et tente de nous renvoyer à un formulaire de login, mais comme celui-ci n'existe pas encore, nous devons le créer dans app/views/users/login.ctp :
<div class="login">
<h2>Login</h2>
<?php echo $form->create('User', array('action' => 'login'));?>
<?php echo $form->input('username');?>
<?php echo $form->input('password');?>
<?php echo $form->submit('Login');?>
<?php echo $form->end(); ?>
</div>
Comme nous avons déclaré la variable $scaffold dans le contôleur, ce qui indique au système qu'il lui appartient de générer les différentes vues élémentaires permettant de créer, modifier et effacer des utilisateurs, l'essentiel du travail est à présent terminé. Toutefois, pour pouvoir réaliser ces opérations il faut être identifié... et il n'existe encore aucun utilistateur dans la base... pas de problème, affinons un peu les choses:
Modifions le contrôleur pour y ajouter la fonction beforeFilter() qui est appelée par le système avant toute autre action de ce contrôleur, ce qui est l'endroit idéal pour s'assurer qu'un utilisateur est bien autorisé. À l'intérieur de cette fonction, une seule ligne qui nous donne tout pouvoir:
function beforeFilter() {
$this->Auth->allow('*');
}
Et voilà, nous pouvons à présent entrer les informations de notre premier utilisateur. Il suffira par la suite de supprimer ou commenter cette ligne pour tester que tout fonctionne bien.
À partir de là, nous pouvons légèrement perfectionner le système et l'affiner en fonctions de l'usage souhaité.
Pour commencer, vous constaterez rapidement qu'en cas d'entrée incorrecte d'identifiant ou de mot de passe, le système se contente de renvoyer le formulaire sans afficher d'erreur... une simple ligne suffit pour arranger ça dans app/views/users/login.ctp :
<div class="login">
<h2>Login</h2>
<?php if ($session->check('Message.auth')) $session->flash('auth'); ?>
<?php echo $form->create('Admin', array('action' => 'login'));?>
<?php echo $form->input('username');?>
<?php echo $form->input('password');?>
<?php echo $form->submit('Login');?>
<?php echo $form->end(); ?>
</div>
Nettement mieux ainsi... le composant 'Auth' utilise la clef 'auth' pour stocker le message d'alerte, c'est pourquoi il faut passer cette clef en paramètre à la fonction flash(). C'est bien joli, mais le message est celui par défaut et ne nous convient pas... qu'à cela ne tienne, nous pouvons en indiquer un autre via la fonction beforeFilter() vue précédemment dans app/controllers/users_controller.php :
function beforeFilter() {
$this->Auth->loginError = __('The information entered is not correct',true);
//$this->Auth->allow('*');
}
Petite finesse au passage. Nous aurions pu nous contenter d'utiliser:
$this->Auth->loginError = 'The information entered is not correct';
Mais l'avantage de la fonction __() nous permet d'envisager que ce message pourrait apparaître dans d'autres langues car il s'agit de la fonction de traduction de CakePHP 1.2. Le second paramètre true signifie que le message doit être assigné à une variable. Sans ce paramètre la phrase serait simplement affichée lors de l'appel à la fonction.